рдЬреЗрдирдХрд┐рдиреНрд╕рдордзреАрд▓ рдПрд╕рдХреНрдпреВрдПрд▓ рд╕рд░реНрд╡реНрд╣рд░рдЪреЗ рдСрдЯреЛрдореЗрд╢рди: рдкрд░рд┐рдгрд╛рдо рд╕реБрдВрджрд░рдкрдгреЗ рдкрд░рдд рдХрд░рдгреЗ

рдкреБрдиреНрд╣рд╛ рд╡реНрдпрд╡рд╕реНрдереЗрдЪреА рдереАрдо рдЪрд╛рд▓реВ рдареЗрд╡рдгреЗ рдЭрд┐рд░реЛ рдЯрдЪ PROD RDS рдЕрдВрддрд░реНрдЧрдд. рднрд╡рд┐рд╖реНрдпрд╛рддреАрд▓ DBAs PROD рд╕рд░реНрд╡реНрд╣рд░рд╢реА рдереЗрдЯ рдХрдиреЗрдХреНрдЯ рдХрд░реВ рд╢рдХрдгрд╛рд░ рдирд╛рд╣реАрдд, рдкрд░рдВрддреБ рддреЗ рд╡рд╛рдкрд░рдгреНрдпрд╛рд╕ рд╕рдХреНрд╖рдо рдЕрд╕рддреАрд▓ рдЬреЗрдирдХрд┐рдиреНрд╕ рдорд░реНрдпрд╛рджрд┐рдд рдСрдкрд░реЗрд╢рдиреНрд╕рд╕рд╛рдареА рдиреЛрдХрд░реНтАНрдпрд╛. рдбреАрдмреАрдПрдиреЗ рдиреЛрдХрд░реА рд╕реБрд░реВ рдХреЗрд▓реА рдЖрдгрд┐ рдХрд╛рд╣реА рдХрд╛рд│рд╛рдирдВрддрд░ рд╣реЗ рдСрдкрд░реЗрд╢рди рдкреВрд░реНрдг рдЭрд╛рд▓реНрдпрд╛рдЪреНрдпрд╛ рдЕрд╣рд╡рд╛рд▓рд╛рд╕рд╣ рдПрдХ рдкрддреНрд░ рдкреНрд░рд╛рдкреНрдд рд╣реЛрддреЗ. рд╣реЗ рдкрд░рд┐рдгрд╛рдо рд╡рд╛рдкрд░рдХрд░реНрддреНрдпрд╛рд▓рд╛ рд╕рд╛рджрд░ рдХрд░рдгреНрдпрд╛рдЪреЗ рдорд╛рд░реНрдЧ рдкрд╛рд╣реВ рдпрд╛.

рдЬреЗрдирдХрд┐рдиреНрд╕рдордзреАрд▓ рдПрд╕рдХреНрдпреВрдПрд▓ рд╕рд░реНрд╡реНрд╣рд░рдЪреЗ рдСрдЯреЛрдореЗрд╢рди: рдкрд░рд┐рдгрд╛рдо рд╕реБрдВрджрд░рдкрдгреЗ рдкрд░рдд рдХрд░рдгреЗ

рд╕рд╛рдзрд╛ рдордЬрдХреВрд░

рдЪрд▓рд╛ рд╕рд░реНрд╡рд╛рдд рдХреНрд╖реБрд▓реНрд▓рдХ рд╕рд╣ рдкреНрд░рд╛рд░рдВрдн рдХрд░реВрдпрд╛. рдкрд╣рд┐рд▓реА рдкрджреНрдзрдд рдЗрддрдХреА рд╕реЛрдкреА рдЖрд╣реЗ рдХреА рддреНрдпрд╛рдмрджреНрджрд▓ рдмреЛрд▓рдгреНрдпрд╛рд╕рд╛рд░рдЦреЗ рдХрд╛рд╣реАрд╣реА рдирд╛рд╣реА (рд▓реЗрдЦрдХ рдпрд╛рдкреБрдвреЗ рдлреНрд░реАрд╕реНрдЯрд╛рдЗрд▓ рдЬреЙрдм рд╡рд╛рдкрд░рддрд╛рдд):

рдЬреЗрдирдХрд┐рдиреНрд╕рдордзреАрд▓ рдПрд╕рдХреНрдпреВрдПрд▓ рд╕рд░реНрд╡реНрд╣рд░рдЪреЗ рдСрдЯреЛрдореЗрд╢рди: рдкрд░рд┐рдгрд╛рдо рд╕реБрдВрджрд░рдкрдгреЗ рдкрд░рдд рдХрд░рдгреЗ

sqlcmd рдХрд╛рд╣реАрддрд░реА рдХрд░рддреЛ рдЖрдгрд┐ рдЖрдореНрд╣реА рддреЗ рд╡рд╛рдкрд░рдХрд░реНрддреНрдпрд╛рд▓рд╛ рд╕рд╛рджрд░ рдХрд░рддреЛ. рдЙрджрд╛рд╣рд░рдгрд╛рд░реНрде, рдмреЕрдХрдЕрдк рдиреЛрдХрд▒реНрдпрд╛рдВрд╕рд╛рдареА рдЖрджрд░реНрд╢:

рдЬреЗрдирдХрд┐рдиреНрд╕рдордзреАрд▓ рдПрд╕рдХреНрдпреВрдПрд▓ рд╕рд░реНрд╡реНрд╣рд░рдЪреЗ рдСрдЯреЛрдореЗрд╢рди: рдкрд░рд┐рдгрд╛рдо рд╕реБрдВрджрд░рдкрдгреЗ рдкрд░рдд рдХрд░рдгреЗ

рд╣реЗ рд╡рд┐рд╕рд░реВ рдирдХрд╛ рдХреА RDS рдмреЕрдХрдЕрдк/рд░рд┐рд╕реНрдЯреЛрд░ рдЕрдВрддрд░реНрдЧрдд рдЕрд╕рд┐рдВрдХреНрд░реЛрдирд╕ рдЖрд╣реЗ, рдореНрд╣рдгреВрди рддреБрдореНрд╣рд╛рд▓рд╛ рддреНрдпрд╛рдЪреА рдкреНрд░рддреАрдХреНрд╖рд╛ рдХрд░рд╛рд╡реА рд▓рд╛рдЧреЗрд▓:

declare @rds table
  (id int, task_type varchar(128), database_name sysname, pct int, duration int, 
   lifecycle varchar(128), taskinfo varchar(max) null, 
   upd datetime, cre datetime,
   s3 varchar(256), ovr int, KMS varchar(256) null)
waitfor delay '00:00:20' 
insert into @rds exec msdb.dbo.rds_task_status @db_name='{db}'
select @xid=max(id) from @rds

again:
waitfor delay '00:00:02'
delete from @rds
insert into @rds exec msdb.dbo.rds_task_status @db_name='{db}' 
# {db} substituted with db name by powershell
select @stat=lifecycle,@info=taskinfo from @rds where id=@xid
if @stat not in ('ERROR','SUCCESS','CANCELLED') goto again

рджреБрд╕рд░реА рдкрджреНрдзрдд, CSV

рдпреЗрдереЗ рд╕рд░реНрд╡ рдХрд╛рд╣реА рдЕрдЧрджреА рд╕реЛрдкреЗ рдЖрд╣реЗ:

рдЬреЗрдирдХрд┐рдиреНрд╕рдордзреАрд▓ рдПрд╕рдХреНрдпреВрдПрд▓ рд╕рд░реНрд╡реНрд╣рд░рдЪреЗ рдСрдЯреЛрдореЗрд╢рди: рдкрд░рд┐рдгрд╛рдо рд╕реБрдВрджрд░рдкрдгреЗ рдкрд░рдд рдХрд░рдгреЗ

рддрдерд╛рдкрд┐, рд╣реА рдкрджреНрдзрдд рдХреЗрд╡рд│ рддреЗрд╡реНрд╣рд╛рдЪ рдХрд╛рд░реНрдп рдХрд░рддреЗ рдЬреЗрд╡реНрд╣рд╛ CSV рдордзреНрдпреЗ рдкрд░рдд рдХреЗрд▓реЗрд▓рд╛ рдбреЗрдЯрд╛ "рд╕рд╛рдзрд╛" рдЕрд╕реЗрд▓. рдЬрд░ рддреБрдореНрд╣реА рдкрд░рдд рдХрд░рдгреНрдпрд╛рдЪрд╛ рдкреНрд░рдпрддреНрди рдХреЗрд▓рд╛ рддрд░, рдЙрджрд╛рд╣рд░рдгрд╛рд░реНрде, TOP N CPU рдЧрд╣рди рдХреНрд╡реЗрд░реАрдВрдЪреА рд╕реВрдЪреА рдЕрд╢рд╛ рдкреНрд░рдХрд╛рд░реЗ, CSV "рдЦреЛрдЦрд▓рд╛" рдЬрд╛рдИрд▓ рдХрд╛рд░рдг рдХреНрд╡реЗрд░реА рдордЬрдХреБрд░рд╛рдд рдХреЛрдгрддреЗрд╣реА рд╡рд░реНрдг рдЕрд╕реВ рд╢рдХрддрд╛рдд - рд╕реНрд╡рд▓реНрдкрд╡рд┐рд░рд╛рдо, рдХреЛрдЯ рдЖрдгрд┐ рдЕрдЧрджреА рд▓рд╛рдЗрди рдмреНрд░реЗрдХ. рдореНрд╣рдгреВрди, рдЖрдореНрд╣рд╛рд▓рд╛ рдХрд╛рд╣реАрддрд░реА рдЕрдзрд┐рдХ рдХреНрд▓рд┐рд╖реНрдЯ рд╣рд╡реЗ рдЖрд╣реЗ.

HTML рдордзреНрдпреЗ рд╕реБрдВрджрд░ рдЪрд┐рдиреНрд╣реЗ

рдореА рд▓рдЧреЗрдЪ рддреБрдореНрд╣рд╛рд▓рд╛ рдХреЛрдб рд╕реНрдирд┐рдкреЗрдЯ рджреЗрдИрди

$Header = @"
<style>
TABLE {border-width: 1px; border-style: solid; border-color: black; border-collapse: collapse;}
TH {border-width: 1px; padding: 3px; border-style: solid; border-color: black; background-color: #6495ED;}
TD {border-width: 1px; padding: 3px; border-style: solid; border-color: black;}
</style>
"@
  
$Result = invoke-Sqlcmd -ConnectionString $jstr -Query "select * from DbInv" `
  | Select-Object -Property * -ExcludeProperty "ItemArray", "RowError", "RowState", "Table", "HasErrors"
if ($Result -eq $null) { $cnt = 0; }
elseif ($Result.getType().FullName -eq "System.Management.Automation.PSCustomObject") { $cnt = 1; }
else { $cnt = $Result.Rows.Count; } 
if ($cnt -gt 0) {
  $body = "<h2>My table</h2>"
  $Result | ConvertTo-HTML -Title "Rows" -Head $header -body $body `
    | Out-File "res.log" -Append -Encoding UTF8
  } else {
    "<h3>No data</h3>" | Out-File "res.log" -Append -Encoding UTF8
  }

рддрд╕реЗ, System.Management.Automation.PSCustomObject рд╕рд╣ рдУрд│реАрдХрдбреЗ рд▓рдХреНрд╖ рджреНрдпрд╛, рддреЗ рдЬрд╛рджреБрдИ рдЖрд╣реЗ; рдЬрд░ рдЧреНрд░рд┐рдбрдордзреНрдпреЗ рдПрдХрдЪ рдУрд│ рдЕрд╕реЗрд▓, рддрд░ рдХрд╛рд╣реА рд╕рдорд╕реНрдпрд╛ рдЙрджреНрднрд╡рд▓реНрдпрд╛. рдлрд╛рд░рд╕рд╛ рди рд╕рдордЬрддрд╛ рдЗрдВрдЯрд░рдиреЗрдЯрд╡рд░реВрди рдЙрдкрд╛рдп рдХрд╛рдврд▓рд╛. рдкрд░рд┐рдгрд╛рдореА, рддреБрдореНрд╣рд╛рд▓рд╛ рдЕрд╕реЗ рдХрд╛рд╣реАрддрд░реА рд╕реНрд╡рд░реВрдкрд┐рдд рдЖрдЙрдЯрдкреБрдЯ рдорд┐рд│реЗрд▓:

рдЬреЗрдирдХрд┐рдиреНрд╕рдордзреАрд▓ рдПрд╕рдХреНрдпреВрдПрд▓ рд╕рд░реНрд╡реНрд╣рд░рдЪреЗ рдСрдЯреЛрдореЗрд╢рди: рдкрд░рд┐рдгрд╛рдо рд╕реБрдВрджрд░рдкрдгреЗ рдкрд░рдд рдХрд░рдгреЗ

рдЖрд▓реЗрдЦ рдХрд╛рдврдгреЗ

рдЪреЗрддрд╛рд╡рдгреА: рдЦрд╛рд▓реА рдХрд┐рдВрдХреА рдХреЛрдб!
рдПрд╕рдХреНрдпреВрдПрд▓ рд╕рд░реНрд╡реНрд╣рд░рд╡рд░ рдПрдХ рдордЬреЗрджрд╛рд░ рдХреНрд╡реЗрд░реА рдЖрд╣реЗ рдЬреА рд╢реЗрд╡рдЯрдЪреНрдпрд╛ рдПрди рдорд┐рдирд┐рдЯрд╛рдВрд╕рд╛рдареА рд╕реАрдкреАрдпреВ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рддреЗ - рдЕрд╕реЗ рджрд┐рд╕реВрди рдЖрд▓реЗ рдХреА рдХреЙрдореНрд░реЗрдб рдореЗрдЬрд░рд▓рд╛ рд╕рд░реНрд╡рдХрд╛рд╣реА рдЖрдард╡рддреЗ! рд╣реА рдХреНрд╡рд┐рдЭ рд╡рд╛рдкрд░реВрди рдкрд╣рд╛:

DECLARE @ts_now bigint = (SELECT cpu_ticks/(cpu_ticks/ms_ticks) 
  FROM sys.dm_os_sys_info WITH (NOLOCK)); 
SELECT TOP(256) 
  DATEADD(ms, -1 * (@ts_now - [timestamp]), GETDATE()) AS [EventTime],
  SQLProcessUtilization AS [SQLCPU], 
  100 - SystemIdle - SQLProcessUtilization AS [OtherCPU]
FROM (SELECT record.value('(./Record/@id)[1]', 'int') AS record_id, 
  record.value('(./Record/SchedulerMonitorEvent/SystemHealth/SystemIdle)[1]', 'int') 
    AS [SystemIdle], 
  record.value('(./Record/SchedulerMonitorEvent/SystemHealth/ProcessUtilization)[1]', 'int') 
    AS [SQLProcessUtilization], [timestamp] 
  FROM (SELECT [timestamp], CONVERT(xml, record) AS [record] 
  FROM sys.dm_os_ring_buffers WITH (NOLOCK)
  WHERE ring_buffer_type = N'RING_BUFFER_SCHEDULER_MONITOR' 
    AND record LIKE N'%<SystemHealth>%') AS x) AS y 
ORDER BY 1 DESC OPTION (RECOMPILE);

рдЖрддрд╛, рд╣реЗ рд╕реНрд╡рд░реВрдкрди рд╡рд╛рдкрд░реВрди ($Fragment рд╡реНрд╣реЗрд░рд┐рдПрдмрд▓)

<table style="width: 100%"><tbody><tr style="background-color: white; height: 2pt;">
  <td style="width: SQLCPU%; background-color: green;"></td>
  <td style="width: OtherCPU%; background-color: blue;"></td>
  <td style="width: REST%; background-color: #C0C0C0;"></td></tr></tbody>
</table>

рдЖрдореНрд╣реА рдЕрдХреНрд╖рд░рд╛рдЪрд╛ рдореБрдЦреНрдп рднрд╛рдЧ рдмрдирд╡реВ рд╢рдХрддреЛ:

$Result = invoke-Sqlcmd -ConnectionString $connstr -Query $Query `
  | Select-Object -Property * -ExcludeProperty `
  "ItemArray", "RowError", "RowState", "Table", "HasErrors"
if ($Result.HasRows) {
  foreach($item in $Result) 
    { 
    $time = $itemEventTime 
    $sqlcpu = $item.SQLCPU
    $other = $itemOtherCPU
    $rest = 100 - $sqlcpu - $other
    $f = $fragment -replace "SQLCPU", $sqlcpu
    $f = $f -replace "OtherCPU", $other
    $f = $f -replace "REST", $rest
    $f | Out-File "res.log" -Append -Encoding UTF8
    }

рдЬреЗ рдпрд╛рд╕рд╛рд░рдЦреЗ рджрд┐рд╕реЗрд▓:

рдЬреЗрдирдХрд┐рдиреНрд╕рдордзреАрд▓ рдПрд╕рдХреНрдпреВрдПрд▓ рд╕рд░реНрд╡реНрд╣рд░рдЪреЗ рдСрдЯреЛрдореЗрд╢рди: рдкрд░рд┐рдгрд╛рдо рд╕реБрдВрджрд░рдкрдгреЗ рдкрд░рдд рдХрд░рдгреЗ

рд╣реЛрдп, рдорд╣рд╛рд╢рдп рд╡рд┐рдХреГрддрд╛рдВрдмрджреНрджрд▓ рдмрд░реЗрдЪ рдХрд╛рд╣реА рдЬрд╛рдгрддрд╛рдд! рд╣реЗ рдордиреЛрд░рдВрдЬрдХ рдЖрд╣реЗ рдХреА рдпрд╛ рдХреЛрдбрдордзреНрдпреЗ рд╣реЗ рд╕рдорд╛рд╡рд┐рд╖реНрдЯ рдЖрд╣реЗ: рдкреЙрд╡рд░рд╢реЗрд▓ (рддреНрдпрд╛рдордзреНрдпреЗ рд▓рд┐рд╣рд┐рд▓реЗрд▓реЗ), SQL, Xquery, HTML. рд╣реА рдЦреЗрджрд╛рдЪреА рдЧреЛрд╖реНрдЯ рдЖрд╣реЗ рдХреА рдЖрдореНрд╣реА HTML рдордзреНрдпреЗ Javascript рдЬреЛрдбреВ рд╢рдХрдд рдирд╛рд╣реА (рдХрд╛рд░рдг рддреЗ рд▓реЗрдЦрдирд╛рд╕рд╛рдареА рдЖрд╣реЗ), рдкрд░рдВрддреБ Python рдХреЛрдб (рдЬреЛ SQL рдордзреНрдпреЗ рд╡рд╛рдкрд░рд▓рд╛ рдЬрд╛рдК рд╢рдХрддреЛ) рдкреЙрд▓рд┐рд╢ рдХрд░рдгреЗ рд╣реЗ рдкреНрд░рддреНрдпреЗрдХрд╛рдЪреЗ рдХрд░реНрддрд╡реНрдп рдЖрд╣реЗ!

SQL рдкреНрд░реЛрдлрд╛рдЗрд▓рд░ рдЯреНрд░реЗрд╕ рдЖрдЙрдЯрдкреБрдЯ

рд╣реЗ рд╕реНрдкрд╖реНрдЯ рдЖрд╣реЗ рдХреА рдЯреЗрдХреНрд╕реНрдЯрдбреЗрдЯрд╛ рдлреАрд▓реНрдбрдореБрд│реЗ рдЯреНрд░реЗрд╕ CSV рдордзреНрдпреЗ рдмрд╕рдгрд╛рд░ рдирд╛рд╣реА. рдкрд░рдВрддреБ рдПрдХрд╛ рдкрддреНрд░рд╛рдд рдЯреНрд░реЗрд╕ рдЧреНрд░рд┐рдб рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рдгреЗ рджреЗрдЦреАрд▓ рд╡рд┐рдЪрд┐рддреНрд░ рдЖрд╣реЗ - рдЖрдХрд╛рд░рд╛рдореБрд│реЗ рдЖрдгрд┐ рдкреБрдвреАрд▓ рд╡рд┐рд╢реНрд▓реЗрд╖рдгрд╛рд╕рд╛рдареА рд╣рд╛ рдбреЗрдЯрд╛ рдмрд░реНтАНрдпрд╛рдЪрджрд╛ рд╡рд╛рдкрд░рд▓рд╛ рдЬрд╛рддреЛ. рдореНрд╣рдгреВрди, рдЖрдореНрд╣реА рдЦрд╛рд▓реАрд▓ рдЧреЛрд╖реНрдЯреА рдХрд░рддреЛ: рдЖрдореНрд╣реА рджреНрд╡рд╛рд░реЗ рдХреЙрд▓ рдХрд░рддреЛ invoke-SqlCmd рдПрдХ рд╡рд┐рд╢рд┐рд╖реНрдЯ рд╕реНрдХреНрд░рд┐рдкреНрдЯ, рдЬреНрдпрд╛рдЪреНрдпрд╛ рдЦреЛрд▓рд╛рдд рддреЗ рдХреЗрд▓реЗ рдЬрд╛рддреЗ

select 
  SPID,EventClass,TextData,
  Duration,Reads,Writes,CPU,
  StartTime,EndTime,DatabaseName,HostName,
  ApplicationName,LoginName
   from ::fn_trace_gettable ( @filename , default )  

рдкреБрдвреЗ, рд╡рд░ рдорд┐рддреНрд░ DBA рджреНрд╡рд╛рд░реЗ рдкреНрд░рд╡реЗрд╢ рдХрд░рдгреНрдпрд╛рдпреЛрдЧреНрдп рд╕рд░реНрд╡реНрд╣рд░рд╡рд░, рд░рд┐рдХреНрдд рдЯреЗрдореНрдкрд▓реЗрдЯрд╕рд╣ рдПрдХ рдЯреНрд░реЗрд╕реЗрд╕ рдбреЗрдЯрд╛рдмреЗрд╕ рдЖрд╣реЗ, рдореЙрдбреЗрд▓ рдкреНрд▓реЗрдЯ, рд╕рд░реНрд╡ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рд╕реНрддрдВрдн рд╕реНрд╡реАрдХрд╛рд░рдгреНрдпрд╛рд╕ рддрдпрд╛рд░ рдЖрд╣реЗ. рдЖрдореНрд╣реА рд╣реЗ рдореЙрдбреЗрд▓ рдПрдХрд╛ рдЕрджреНрд╡рд┐рддреАрдп рдирд╛рд╡рд╛рд╕рд╣ рдирд╡реАрди рдЯреЗрдмрд▓рд╡рд░ рдХреЙрдкреА рдХрд░рддреЛ:

$dt = Get-Date -format "yyyyMMdd"
$tm = Get-Date -format "hhmmss"
$tableName = $srv + "_" + $dt + "_" + $tm
$copytab = "select * into " + $tableName + " from Model"
invoke-SqlCmd -ConnectionString $tstr -Query $copytab 

рдЖрдгрд┐ рдЖрддрд╛ рдЖрдкрдг рддреНрдпрд╛рдЪрд╛ рд╡рд╛рдкрд░ рдХрд░реВрди рдЖрдкрд▓рд╛ рдЯреНрд░реЗрд╕ рд▓рд┐рд╣реВ рд╢рдХрддреЛ рдбреЗрдЯрд╛.SqlClient.SqlBulkCopy - рдпрд╛рдЪреЗ рдЙрджрд╛рд╣рд░рдг рдореА рд╡рд░ рджрд┐рд▓реЗ рдЖрд╣реЗ. рд╣реЛрдп, TextData рдордзреНрдпреЗ рд╕реНрдерд┐рд░рд╛рдВрдХ рдорд╛рд╕реНрдХ рдХрд░рдгреЗ рджреЗрдЦреАрд▓ рдЪрд╛рдВрдЧрд▓реЗ рд╣реЛрдИрд▓:

# mask data
foreach ($Row in $Result)
{ 
  $v = $Row["TextData"]
  $v = $v -replace "'([^']{2,})'", "'str'" -replace "[0-9][0-9]+", '999'
  $Row["TextData"] = $v
}

рдЖрдореНрд╣реА рдПрдХрд╛ рд╡рд░реНрдгрд╛рдкреЗрдХреНрд╖рд╛ рдЬрд╛рд╕реНрдд рд▓рд╛рдВрдмреАрдЪреНрдпрд╛ рд╕рдВрдЦреНрдпрд╛рдВрдирд╛ 999 рдиреЗ рдмрджрд▓рддреЛ рдЖрдгрд┐ рдЖрдореНрд╣реА рдПрдХрд╛ рд╡рд░реНрдгрд╛рдкреЗрдХреНрд╖рд╛ рдЬрд╛рд╕реНрдд рд▓рд╛рдВрдмреАрдЪреНрдпрд╛ рд╕реНрдЯреНрд░рд┐рдВрдЧреНрд╕рдЪреНрдпрд╛ рдЬрд╛рдЧреА 'str' рдареЗрд╡рддреЛ. 0 рддреЗ 9 рдкрд░реНрдпрдВрддрдЪреНрдпрд╛ рдЕрдВрдХрд╛рдВрдЪрд╛ рд╡рд╛рдкрд░ рдЕрдиреЗрдХрджрд╛ рдзреНрд╡рдЬ рдореНрд╣рдгреВрди рдХреЗрд▓рд╛ рдЬрд╛рддреЛ рдЖрдгрд┐ рдЖрдореНрд╣реА рддреНрдпрд╛рдВрдирд╛ рд╕реНрдкрд░реНрд╢ рдХрд░рдд рдирд╛рд╣реА, рддрд╕реЗрдЪ рд░рд┐рдХреНрдд рдЖрдгрд┐ рдПрдХрд▓-рдЕрдХреНрд╖рд░рд╛рдВрдЪреНрдпрд╛ рддрд╛рд░ - 'Y', 'N', рдЗрддреНрдпрд╛рджрд┐ рдЕрдиреЗрдХрджрд╛ рдЖрдврд│рддрд╛рдд.

рдЪрд▓рд╛ рдЖрдкрд▓реНрдпрд╛ рдЖрдпреБрд╖реНрдпрд╛рдд рдХрд╛рд╣реА рд░рдВрдЧ рднрд░реВрдпрд╛ (рдХрдареЛрд░рдкрдгреЗ 18+)

рд╕рд╛рд░рдгреНрдпрд╛рдВрдордзреНрдпреЗ, рдЖрдкрдг рдЕрдиреЗрдХрджрд╛ рд▓рдХреНрд╖ рджреЗрдгреНрдпрд╛рдЪреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдЕрд╕рд▓реЗрд▓реНрдпрд╛ рд╕реЗрд▓ рд╣рд╛рдпрд▓рд╛рдЗрдЯ рдХрд░реВ рдЗрдЪреНрдЫрд┐рдд рдЖрд╣рд╛рдд. рдЙрджрд╛рд╣рд░рдгрд╛рд░реНрде, рдЕрдпрд╢рд╕реНрд╡реА, рдЙрдЪреНрдЪ рдкрд╛рддрд│реАрдЪреЗ рд╡рд┐рдЦрдВрдбрди рдЗ. рдЕрд░реНрдерд╛рдд, рд╣реЗ рдмреЗрдЕрд░ рдПрд╕рдХреНрдпреВрдПрд▓рдордзреНрдпреЗ рдХреЗрд▓реЗ рдЬрд╛рдК рд╢рдХрддреЗ, рдкреНрд░рд┐рдВрдЯ рд╡рд╛рдкрд░реВрди рдПрдЪрдЯреАрдПрдордПрд▓ рддрдпрд╛рд░ рдХрд░рдгреЗ рдЖрдгрд┐ рдЬреЗрдирдХрд┐рдиреНрд╕рдордзреНрдпреЗ рдлрд╛рдЗрд▓ рдкреНрд░рдХрд╛рд░ рдПрдЪрдЯреАрдПрдордПрд▓рд╡рд░ рд╕реЗрдЯ рдХрд░рдгреЗ:

declare @body varchar(max), @chunk varchar(max)
set @body='<font face="Lucida Console" size="3">'
set @body=@body+'<b>Server name: '+@@servername+'</b><br>'
set @body=@body+'<br><br>'
set @body=@body+'<table><tr><th>Job</th><th>Last Run</th><th>Avg Duration, sec</th><th>Last Run, Sec</th><th>Last Status</th></tr>'
print @body

DECLARE tab CURSOR FOR SELECT '<tr><td>'+name+'</td><td>'+
  LastRun+'</td><td>'+
  convert(varchar,AvgDuration)+'</td><td>'+
  convert(varchar,LastDuration)+'</td><td>'+
    case when LastStatus<>'Succeeded' then '<font color="red">' else '' end+
      LastStatus+
      case when LastStatus<>'Succeeded' then '</font>' else '' end+
     +'</td><td>'
  from #j2
OPEN tab;  
FETCH NEXT FROM tab into @chunk
WHILE @@FETCH_STATUS = 0  
BEGIN
  print @chunk
  FETCH NEXT FROM tab into @chunk;  
END  
CLOSE tab;  
DEALLOCATE tab;
print '</table>'

рдореА рдЕрд╕рд╛ рдХреЛрдб рдХрд╛ рд▓рд┐рд╣рд┐рд▓рд╛?

рдЬреЗрдирдХрд┐рдиреНрд╕рдордзреАрд▓ рдПрд╕рдХреНрдпреВрдПрд▓ рд╕рд░реНрд╡реНрд╣рд░рдЪреЗ рдСрдЯреЛрдореЗрд╢рди: рдкрд░рд┐рдгрд╛рдо рд╕реБрдВрджрд░рдкрдгреЗ рдкрд░рдд рдХрд░рдгреЗ

рдкрдг рддреНрдпрд╛рд╣реВрди рд╕реБрдВрджрд░ рдЙрдкрд╛рдп рдЖрд╣реЗ. рдХрдиреНрд╡реНрд╣рд░реНрдЯ рдЯреВ-HTML рдЖрдореНрд╣рд╛рд▓рд╛ рдкреЗрд╢реАрдВрдирд╛ рд░рдВрдЧ рджреЗрдК рджреЗрдд рдирд╛рд╣реА, рдкрд░рдВрддреБ рд╡рд╕реНрддреБрд╕реНрдерд┐рддреАрдирдВрддрд░ рдЖрдореНрд╣реА рддреЗ рдХрд░реВ рд╢рдХрддреЛ. рдЙрджрд╛рд╣рд░рдгрд╛рд░реНрде, рдЖрдореНрд╣рд╛рд▓рд╛ 80 рдкреЗрдХреНрд╖рд╛ рдЬрд╛рд╕реНрдд рдЖрдгрд┐ 90 рдкреЗрдХреНрд╖рд╛ рдЬрд╛рд╕реНрдд рд╡рд┐рдЦрдВрдбрди рдкрд╛рддрд│реА рдЕрд╕рд▓реЗрд▓реЗ рд╕реЗрд▓ рдирд┐рд╡рдбрд╛рдпрдЪреЗ рдЖрд╣реЗрдд. рдЪрд▓рд╛ рд╢реИрд▓реА рдЬреЛрдбреВрдпрд╛:

<style>
.SQLmarkup-red { color: red; background-color: yellow; }
.SQLmarkup-yellow { color: black; background-color: #FFFFE0; }
.SQLmarkup-default { color: black; background-color: white; }
</style>

рдХреНрд╡реЗрд░реАрдордзреНрдпреЗрдЪ рдЖрдкрдг рдПрдХ рдбрдореА рдХреЙрд▓рдо рдЬреЛрдбреВ рд▓рдЧреЗрдЪ рдЖрдзреА рд╕реНрддрдВрдн рдЖрдореНрд╣рд╛рд▓рд╛ рд░рдВрдЧрд╛рдпрдЪрд╛ рдЖрд╣реЗ. рдХреЙрд▓рдо рдмреЛрд▓рд╛рд╡рд▓реЗ рдкрд╛рд╣рд┐рдЬреЗ SQLmarkup-рдХрд╛рд╣реАрддрд░реА:

case  
  when ps.avg_fragmentation_in_percent>=90.0 then 'SQLmarkup-red'
  when ps.avg_fragmentation_in_percent>=80.0 then 'SQLmarkup-yellow'
  else 'SQLmarkup-default' 
  end as [SQLmarkup-1], 
ps.avg_fragmentation_in_percent, 

рдЖрддрд╛, рдкреЙрд╡рд░рд╢реЗрд▓рджреНрд╡рд╛рд░реЗ рд╡реНрдпреБрддреНрдкрдиреНрди рдХреЗрд▓реЗрд▓реЗ HTML рдкреНрд░рд╛рдкреНрдд рдЭрд╛рд▓реНрдпрд╛рдирдВрддрд░, рдЖрдореНрд╣реА рд╣реЗрдбрд░рдордзреВрди рдбрдореА рдХреЙрд▓рдо рдХрд╛рдвреВрди рдЯрд╛рдХреВ рдЖрдгрд┐ рдбреЗрдЯрд╛рдЪреНрдпрд╛ рдореБрдЦреНрдп рднрд╛рдЧрд╛рдордзреНрдпреЗ рдЖрдореНрд╣реА рдХреЙрд▓рдордордзреВрди рд╕реНрдЯрд╛рдЗрд▓рдордзреНрдпреЗ рдореВрд▓реНрдп рд╣рд╕реНрддрд╛рдВрддрд░рд┐рдд рдХрд░реВ. рд╣реЗ рдлрдХреНрдд рджреЛрди рдкреНрд░рддрд┐рд╕реНрдерд╛рдкрдирд╛рдВрд╕рд╣ рдХреЗрд▓реЗ рдЬрд╛рддреЗ:

$html = $html `
  -replace "<th>SQLmarkup[^<]*</th>", "" `
  -replace "<td>SQLmarkup-(.+?)</td><td>",'<td class="SQLmarkup-$1">'

рдирд┐рдХрд╛рд▓:
рдЬреЗрдирдХрд┐рдиреНрд╕рдордзреАрд▓ рдПрд╕рдХреНрдпреВрдПрд▓ рд╕рд░реНрд╡реНрд╣рд░рдЪреЗ рдСрдЯреЛрдореЗрд╢рди: рдкрд░рд┐рдгрд╛рдо рд╕реБрдВрджрд░рдкрдгреЗ рдкрд░рдд рдХрд░рдгреЗ

рддреЗ рд╢реЛрднрд┐рд╡рдВрдд рдирд╛рд╣реА рдХрд╛? рдирд╛рд╣реА рддрд░реА, рд╣рд╛ рд░рдВрдЧ рдорд▓рд╛ рдХрд╛рд╣реАрддрд░реА рдЖрдард╡рдг рдХрд░реВрди рджреЗрддреЛ
рдЬреЗрдирдХрд┐рдиреНрд╕рдордзреАрд▓ рдПрд╕рдХреНрдпреВрдПрд▓ рд╕рд░реНрд╡реНрд╣рд░рдЪреЗ рдСрдЯреЛрдореЗрд╢рди: рдкрд░рд┐рдгрд╛рдо рд╕реБрдВрджрд░рдкрдгреЗ рдкрд░рдд рдХрд░рдгреЗ

рд╕реНрддреНрд░реЛрдд: www.habr.com

рдПрдХ рдЯрд┐рдкреНрдкрдгреА рдЬреЛрдбрд╛