When does it make sense to import unsealed MP (Ops console) or import only the lastest MP when replacing SCOM 2012 R2 with SCOM 2019? - scom

We are standing up a new SCOM 2019 beside curent SCOM 2012 R2.
Will exporting an MP delete or disable the original MP in Ops console (SCOM 2012 R2)?
Considering exporting unsealed MP from SCOM 2012 R2 to import into SCOM 2019?,... would this be worth the effort to import these or is it better to import the latest MPs? These are old MPs and I have no idea of the interdepedencies because of custom MP for overrides,... does this make sense to start from the beginning with brand new latest MPs.

I would recommend starting fresh with your MPs. You can use the following script to grab all the overrides in your environment. After you run the SCOM Data Collector check under the output zip file: CSV\Overrides.csv
https://aka.ms/SCOM-DataCollector
ALTERNATIVELY
You can also use the following TSQL Query to gather all the Overrides set in your SCOM Environment, run against the OperationsManager DB:
Select WorkflowType, WorkflowName, Overview.OverrideName, OverrideableParameterName, OverrideValue, OverrideDescription, OverrideEnforced, OverrideScope, TargetedInstanceName, TargetedInstancePath, ORMPName, ORMPDescription, ORMPSealed, MPTargetClass, TargetManagementPack, ModuleOverrideId, ORMPLanguage, OverrideLastModified, OverrideCreatedOn from (
SELECT 'Rule' AS 'WorkflowType',
rv.displayname AS WorkflowName,
OverrideName,
op.OverrideableParameterName,
mo.value AS OverrideValue,
lt.ltvalue AS OverrideDescription,
mo.enforced AS OverrideEnforced,
mt.typename AS OverrideScope,
bme.displayname AS TargetedInstanceName,
bme.path AS TargetedInstancePath,
mpv.displayname AS ORMPName,
mpv.description AS ORMPDescription,
mpv.sealed AS ORMPSealed,
mpv.LanguageCode AS ORMPLanguage,
mo.lastmodified AS OverrideLastModified,
mo.timeadded AS OverrideCreatedOn
--op.TimeAdded AS MPTimeCreated
FROM moduleoverride mo
INNER JOIN managementpackview mpv
ON mpv.id = mo.managementpackid
INNER JOIN ruleview rv
ON rv.id = mo.parentid
INNER JOIN managedtype mt
ON mt.managedtypeid = mo.typecontext
LEFT JOIN localizedtext lt
ON lt.ltstringid = mo.moduleoverrideid
LEFT JOIN basemanagedentity bme
ON bme.basemanagedentityid = mo.instancecontext
LEFT JOIN overrideableparameter op
ON mo.overrideableparameterid = op.overrideableparameterid
--Where (lt.LTStringType = 2 and mpv.LanguageCode = 'ENU')
--Where (mpv.Sealed = 0 and mpv.LanguageCode = 'ENU')
--Where mpv.Sealed = 0
UNION ALL
SELECT 'Monitor' AS 'WorkflowType',
mv.displayname AS WorkflowName,
OverrideName,
op.OverrideableParameterName,
mto.value AS OverrideValue,
lt.ltvalue AS OverrideDescription,
mto.enforced AS OverrideEnforced,
mt.typename AS OverrideScope,
bme.displayname AS TargetedInstanceName,
bme.path AS TargetedInstancePath,
mpv.displayname AS ORMPName,
mpv.description AS ORMPDescription,
mpv.sealed AS ORMPSealed,
mpv.LanguageCode AS ORMPLanguage,
mto.lastmodified AS OverrideLastModified,
mto.timeadded AS OverrideCreatedOn
--mpv.TimeCreated AS MPTimeCreated
FROM monitoroverride mto
INNER JOIN managementpackview mpv
ON mpv.id = mto.managementpackid
INNER JOIN monitorview mv
ON mv.id = mto.monitorid
INNER JOIN managedtype mt
ON mt.managedtypeid = mto.typecontext
LEFT JOIN localizedtext lt
ON lt.ltstringid = mto.monitoroverrideid
LEFT JOIN basemanagedentity bme
ON bme.basemanagedentityid = mto.instancecontext
LEFT JOIN overrideableparameter op
ON mto.overrideableparameterid = op.overrideableparameterid
--Where (lt.LTStringType = 2 and mpv.LanguageCode = 'ENU')
--Where (mpv.Sealed = 0 and mpv.LanguageCode = 'ENU')
--Where mpv.Sealed = 0
UNION ALL
SELECT 'Discovery' AS 'WorkflowType',
dv.displayname AS WorkflowName,
OverrideName,
op.OverrideableParameterName,
mo.value AS OverrideValue,
lt.ltvalue AS OverrideDescription,
mo.enforced AS OverrideEnforced,
mt.typename AS OverrideScope,
bme.displayname AS TargetedInstanceName,
bme.path AS TargetedInstancePath,
mpv.displayname AS ORMPName,
mpv.description AS ORMPDescription,
mpv.sealed AS ORMPSealed,
mpv.LanguageCode AS ORMPLanguage,
mo.lastmodified AS OverrideLastModified,
mo.timeadded AS OverrideCreatedOn
--mpv.TimeCreated AS MPTimeCreated
FROM moduleoverride mo
INNER JOIN managementpackview mpv
ON mpv.id = mo.managementpackid
INNER JOIN discoveryview dv
ON dv.id = mo.parentid
INNER JOIN managedtype mt
ON mt.managedtypeid = mo.typecontext
LEFT JOIN localizedtext lt
ON lt.ltstringid = mo.moduleoverrideid
LEFT JOIN basemanagedentity bme
ON bme.basemanagedentityid = mo.instancecontext
LEFT JOIN overrideableparameter op
ON mo.overrideableparameterid = op.overrideableparameterid
--Where (lt.LTStringType = 2 and mpv.LanguageCode = 'ENU')
--Where (mpv.Sealed = 0 and mpv.LanguageCode = 'ENU')
)Overview
LEFT JOIN (
SELECT mo.ModuleOverrideId, mo.OverrideName, mpv.DisplayName as 'MPTargetClass', mpv.FriendlyName as [TargetManagementPack] FROM ModuleOverride mo
INNER JOIN Managedtype mt on mt.ManagedTypeId = mo.TypeContext
INNER JOIN ManagementPackView mpv on mpv.ID = mt.ManagementPackId
Where mpv.LanguageCode = 'ENU'
) OverridesOverview ON OverridesOverview.OverrideName = Overview.OverrideName
ORDER BY OverrideLastModified DESC
Doing this will keep you from adding back in potential issues from your SCOM 2012 R2 environment into the SCOM 2019 environment.
If you are doing a side-by-side migration, you should check out this post on side-by-side migrations:
https://learn.microsoft.com/en-us/answers/questions/167044/whats-the-best-practice-to-migrate-scom-2012-to-sc.html

Related

SQL using data field twice

I currently have the following:
SELECT TblSchoolManagementForms.txtForm, TblPupilManagementPupils.txtSchoolID, TblPupilManagementPupils.txtSurname, TblPupilManagementPupils.txtForename,
TblStaff.Fullname AS TutorFullName, TblStaff.SchoolEmailAddress, TblSchoolManagementYears.txtYearTutor, TblSchoolManagementYears.txtAsstYearTutor
FROM TblPupilManagementPupils INNER JOIN
TblSchoolManagementForms ON TblPupilManagementPupils.txtForm = TblSchoolManagementForms.txtForm INNER JOIN
TblStaff ON TblSchoolManagementForms.txtFormTutor = TblStaff.User_Code INNER JOIN
TblSchoolManagementYears ON TblPupilManagementPupils.intNCYear = TblSchoolManagementYears.intNCYear AND
TblSchoolManagementForms.intNCYear = TblSchoolManagementYears.intNCYear
WHERE TblSchoolManagementYears.intNCYear > 6
UNION
SELECT TblSchoolManagementForms.txtForm, TblPupilManagementPupils.txtSchoolID, TblPupilManagementPupils.txtSurname, TblPupilManagementPupils.txtForename,
TblStaff.Fullname AS TutorFullName, TblStaff.SchoolEmailAddress, TblSchoolManagementYears.txtYearTutor, TblSchoolManagementYears.txtAsstYearTutor
FROM TblPupilManagementPupils INNER JOIN
TblSchoolManagementForms ON TblPupilManagementPupils.txtForm = TblSchoolManagementForms.txtForm INNER JOIN
TblStaff ON TblSchoolManagementForms.txtAsstFormTutor = TblStaff.User_Code INNER JOIN
TblSchoolManagementYears ON TblPupilManagementPupils.intNCYear = TblSchoolManagementYears.intNCYear AND
TblSchoolManagementForms.intNCYear = TblSchoolManagementYears.intNCYear
WHERE TblSchoolManagementYears.intNCYear > 6
This is working beautifully, but I need to add in some additional columns that also link back to TblStaff.User_Code My design currently looks like this, the highlighted fields are the ones I need to link in my query:
What I need to do is add 2 additional columns, 1 for HoYEmail and one for AsstHoYEmail using txtYearTutor linked by User_Code as TblStaff.SchoolEmailAddress AS HoYEmail and the AsstYearTutor linked by User_Code as TblStaff.SchoolEmailAddress AS AsstHoYEmail all grouped by TblPupilManagementPupils.txtSchoolID
Producing something like this:
Any tips gratefully received.
After a bit of research, I ended up completely re-writing this query to get it to work using correlation names for the staff table.
SELECT TblSchoolManagementForms.txtForm, TblPupilManagementPupils.txtSchoolID, TblPupilManagementPupils.txtSurname, TblPupilManagementPupils.txtForename,
TblStaff.SchoolEmailAddress AS TutorEmail, TblStaff_1.SchoolEmailAddress AS HoYEmail, TblStaff_2.SchoolEmailAddress AS AsstHoYEmail
FROM TblStaff INNER JOIN
TblPupilManagementPupils INNER JOIN
TblSchoolManagementForms ON TblPupilManagementPupils.txtForm = TblSchoolManagementForms.txtForm ON
TblStaff.User_Code = TblSchoolManagementForms.txtFormTutor INNER JOIN
TblSchoolManagementYears ON TblPupilManagementPupils.intNCYear = TblSchoolManagementYears.intNCYear INNER JOIN
TblStaff AS TblStaff_1 ON TblSchoolManagementYears.txtYearTutor = TblStaff_1.User_Code INNER JOIN
TblStaff AS TblStaff_2 ON TblSchoolManagementYears.txtAsstYearTutor = TblStaff_2.User_Code
WHERE (TblSchoolManagementYears.intNCYear > 6) AND (TblPupilManagementPupils.intSystemStatus = 1)
UNION
SELECT TblSchoolManagementForms.txtForm, TblPupilManagementPupils.txtSchoolID, TblPupilManagementPupils.txtSurname, TblPupilManagementPupils.txtForename,
TblStaff.SchoolEmailAddress AS TutorEmail, TblStaff_1.SchoolEmailAddress AS HoYEmail, TblStaff_2.SchoolEmailAddress AS AsstHoYEmail
FROM TblStaff INNER JOIN
TblPupilManagementPupils INNER JOIN
TblSchoolManagementForms ON TblPupilManagementPupils.txtForm = TblSchoolManagementForms.txtForm ON
TblStaff.User_Code = TblSchoolManagementForms.txtAsstFormTutor INNER JOIN
TblSchoolManagementYears ON TblPupilManagementPupils.intNCYear = TblSchoolManagementYears.intNCYear INNER JOIN
TblStaff AS TblStaff_1 ON TblSchoolManagementYears.txtYearTutor = TblStaff_1.User_Code INNER JOIN
TblStaff AS TblStaff_2 ON TblSchoolManagementYears.txtAsstYearTutor = TblStaff_2.User_Code
WHERE (TblSchoolManagementYears.intNCYear > 6) AND (TblPupilManagementPupils.intSystemStatus = 1)

Filter using NOT IN with more than one column

Is there a better way to write the following query to minimize code repetition in the WHERE statement?
SELECT TA.*
FROM TA
JOIN TB on TA.id = TB.id
JOIN TC on TB.id =TC.id
JOIN TD on TC.id = TD.id
JOIN TE on TD.id = TE.id
WHERE TC.Name NOT IN (‘John’,’William’,’Jacob’,’Henry’,’David’)
AND TD.Name NOT IN (‘John’,’William’,’Jacob’,’Henry’,’David’)
AND TE.Name NOT IN (‘John’,’William’,’Jacob’,’Henry’,’David’)
Note: The filter is always the same: NOT IN (‘John’,’William’,’Jacob’,’Henry’,’David’)
Using exists with a table value constructor you can do something like this:
SELECT TA.*
FROM TA
JOIN TB on TA.id = TB.id
JOIN TC on TB.id =TC.id
JOIN TD on TC.id = TD.id
JOIN TE on TD.id = TE.id
WHERE NOT EXISTS (
SELECT 1
FROM (VALUES('John'),('William'),('Jacob'),('Henry'),('David')) V(name)
WHERE Name IN(TC.Name, TD.Name, TE.Name)
)

PostgreSQL - weird query planner behavior

Assume I have a query like this:
SELECT *
FROM clients c
INNER JOIN clients_balances cb ON cb.id_clients = c.id
LEFT JOIN clients com ON com.id = c.id_companies
LEFT JOIN clients com_real ON com_real.id = c.id_companies_real
LEFT JOIN rate_tables rt_orig ON rt_orig.id = c.orig_rate_table
LEFT JOIN rate_tables rt_term ON rt_term.id = c.term_rate_table
LEFT JOIN payment_terms pt ON pt.id = c.id_payment_terms
LEFT JOIN paygw_clients_profiles cpgw ON (cpgw.id_clients = c.id AND cpgw.id_companies = c.id_companies_real)
WHERE
EXISTS (SELECT * FROM accounts WHERE (name LIKE 'x' OR accname LIKE 'x' OR ani LIKE 'x') AND id_clients = c.id)
AND c."type" = '0'
AND c."id" > 0
ORDER BY c."name";
This query takes around 35 seconds to run when used in the production environment ("clients" has about 1 million records). However, if I take out ANY join - the query will take only about 300 ms to execute.
I've played around with the query planner settings, but to no avail.
Here are a few explain analyze outputs:
http://explain.depesz.com/s/hzy (slow - 48049.574 ms)
http://explain.depesz.com/s/FWCd (fast - 286.234 ms, rate_tables JOIN removed)
http://explain.depesz.com/s/MyRf (fast - 539.733 ms, paygw_clients_profiles JOIN removed)
It looks like in the fast case the planner starts from the EXISTS statement and has to perform join for only two rows in total. However, in the slow case it will first join all the tables and then filter by EXISTS.
What I need to do is to make this query run in a reasonable time with all seven join in place.
Postgres version is 9.3.10 on CentOS 6.3.
Thanks.
UPDATE
Rewriting the query like this:
SELECT *
FROM clients c
INNER JOIN clients_balances cb ON cb.id_clients = c.id
INNER JOIN accounts a ON a.id_clients = c.id AND (a.name = 'x' OR a.accname = 'x' OR a.ani = 'x')
LEFT JOIN clients com ON com.id = c.id_companies
LEFT JOIN clients com_real ON com_real.id = c.id_companies_real
LEFT JOIN rate_tables rt_orig ON rt_orig.id = c.orig_rate_table
LEFT JOIN rate_tables rt_term ON rt_term.id = c.term_rate_table
LEFT JOIN payment_terms pt ON pt.id = c.id_payment_terms
LEFT JOIN paygw_clients_profiles cpgw ON (cpgw.id_clients = c.id AND cpgw.id_companies = c.id_companies_real)
WHERE
c."type" = '0' AND c.id > 0
ORDER BY c."name";
makes it run fast, however, this is not acceptable, as account filtration parameters are optional, and I still need the result if there are no matches in that table. Using "LEFT JOIN accounts" instead of "INNER JOIN accounts" kills the performance again.
As suggested by Tome Lane, I've changed the following two parameters: join_collapse_limit and from_collapse_limit to 10 instead of the default 8, and this solved the issue.

Postgres UPDATE statement

I have moved from mysql to psql, but find it hard to get my head around the UPDATE statement using multiple left joins.
How would you rewrite this in Postgres? (I am using postresql 9.4)
update task t
left join project p on t.project_id = p.id
left join client c on t.client_id = c.id
left join user u on t.user_id = u.id
set t.project_name = p.name,
t.client_name = c.name,
t.user_name = u.name;
Any pointer will be welcome.
Here you go:
WITH task_data AS (
SELECT t.id,
p.name AS project_name,
c.name AS client_name,
u.name AS user_name
FROM task t
LEFT JOIN project p ON t.project_id = p.id
LEFT JOIN client c ON t.client_id = c.id
LEFT JOIN "user" u ON t.user_id = u.id
)
UPDATE task t
FROM task_data d
SET
project_name = d.project_name,
client_name = d.client_name,
user_name = d.user_name
WHERE t.id = d.id
I would be curious to see if there is a more efficient way

Eliminating NULL rows in TSQL query [duplicate]

This question already has an answer here:
Closed 10 years ago.
Possible Duplicate:
How to eliminate NULL fields in TSQL
I am using SSMS 2008 R2 and am developing a TSQL query. I want just 1 record / profile_name. Because some of these values are NULL, I am currently doing LEFT JOINS on most of the tables. But the problem with the LEFT JOINs is that now I get > 1 record for some profile_names!
But if I change this to INNER JOINs then some profile_names are excluded entirely because they have NULL values for these columns. How do I limit the query result to just one record / profile_name regardless of NULL values? And if there are non-NULL values then I want it to choose the record with non-NULL values. Here is initial query:
select distinct
gp.group_profile_id,
gp.profile_name,
gp.license_number,
gp.is_accepting,
case when gp.is_accepting = 1 then 'Yes'
when gp.is_accepting = 0 then 'No '
end as is_accepting_placement,
mo.profile_name as managing_office,
regions.[region_description] as region,
pv.vendor_name,
pv.id as vendor_id,
at.description as applicant_type,
dbo.GetGroupAddress(gp.group_profile_id, null, 0) as [Office Address],
gsv.status_description
from group_profile gp With (NoLock)
inner join group_profile_type gpt With (NoLock) on gp.group_profile_type_id = gpt.group_profile_type_id and gpt.type_code = 'FOSTERHOME' and gp.agency_id = #agency_id and gp.is_deleted = 0
inner join group_profile mo With (NoLock) on gp.managing_office_id = mo.group_profile_id
left outer join payor_vendor pv With (NoLock) on gp.payor_vendor_id = pv.payor_vendor_id
left outer join applicant_type at With (NoLock) on gp.applicant_type_id = at.applicant_type_id and at.is_foster_home = 1
inner join group_status_view gsv With (NoLock) on gp.group_profile_id = gsv.group_profile_id and gsv.status_value = 'OPEN' and gsv.effective_date =
(Select max(b.effective_date) from group_status_view b With (NoLock)
where gp.group_profile_id = b.group_profile_id)
left outer join regions With (NoLock) on isnull(mo.regions_id, gp.regions_id) = regions.regions_id
left join enrollment en on en.group_profile_id = gp.group_profile_id
join event_log el on el.event_log_id = en.event_log_id
left join people client on client.people_id = el.people_id
As you can see, the results of the above query is 1 row / profile_name:
group_profile_id profile_name license_number is_accepting is_accepting_placement managing_office region vendor_name vendor_id applicant_type Office Address status_description Cert Date2
But now watch what happens when I add in 2 LEFT JOINs and 1 additional column:
select distinct
gp.group_profile_id,
gp.profile_name,
gp.license_number,
gp.is_accepting,
case when gp.is_accepting = 1 then 'Yes'
when gp.is_accepting = 0 then 'No '
end as is_accepting_placement,
mo.profile_name as managing_office,
regions.[region_description] as region,
pv.vendor_name,
pv.id as vendor_id,
at.description as applicant_type,
dbo.GetGroupAddress(gp.group_profile_id, null, 0) as [Office Address],
gsv.status_description,
ri.[description] as race
from group_profile gp With (NoLock)
inner join group_profile_type gpt With (NoLock) on gp.group_profile_type_id = gpt.group_profile_type_id and gpt.type_code = 'FOSTERHOME' and gp.agency_id = #agency_id and gp.is_deleted = 0
inner join group_profile mo With (NoLock) on gp.managing_office_id = mo.group_profile_id
left outer join payor_vendor pv With (NoLock) on gp.payor_vendor_id = pv.payor_vendor_id
left outer join applicant_type at With (NoLock) on gp.applicant_type_id = at.applicant_type_id and at.is_foster_home = 1
inner join group_status_view gsv With (NoLock) on gp.group_profile_id = gsv.group_profile_id and gsv.status_value = 'OPEN' and gsv.effective_date =
(Select max(b.effective_date) from group_status_view b With (NoLock)
where gp.group_profile_id = b.group_profile_id)
left outer join regions With (NoLock) on isnull(mo.regions_id, gp.regions_id) = regions.regions_id
left join enrollment en on en.group_profile_id = gp.group_profile_id
join event_log el on el.event_log_id = en.event_log_id
left join people client on client.people_id = el.people_id
left join race With (NoLock) on el.people_id = race.people_id
left join race_info ri with (nolock) on ri.race_info_id = race.race_info_id
The above query results in all of the same profile_names, but some with NULL race values:
group_profile_id profile_name license_number is_accepting is_accepting_placement managing_office region vendor_name vendor_id applicant_type Office Address status_description Cert Date2 race
Unfortunately it complicates matters that I need to join in 2 additional tables for this one additional field value (race). If I simply change the last two LEFT JOINs above to INNER JOINs then I eliminate the NULL rows above. But I also eliminate some of the profile_names:
group_profile_id profile_name license_number is_accepting is_accepting_placement managing_office region vendor_name vendor_id applicant_type Office Address status_description Cert Date2 race
Hopefully I have provided all of the details that you need for this question.
Not the most elegant solution, but one that will work:
select [stuff]
from group_profile gp With (NoLock)
inner join group_profile_type gpt With (NoLock) on gp.group_profile_type_id = gpt.group_profile_type_id and gpt.type_code = 'FOSTERHOME' and gp.agency_id = #agency_id and gp.is_deleted = 0
inner join group_profile mo With (NoLock) on gp.managing_office_id = mo.group_profile_id
join payor_vendor pv on ISNULL(gp.payor_vendor_id, 'THISVALUEWILLNEVEROCCUR') = ISNULL(pv.payor_vendor_id, 'THISVALUEWILLNEVEROCCUR')
...etc...
Biggest issue with what I posted is that you'll be doing a whole lot of table scans.