<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Steve Rezhener, Author at SQL Solutions Group</title>
	<atom:link href="https://sqlsolutionsgroup.com/author/stever/feed/" rel="self" type="application/rss+xml" />
	<link>https://sqlsolutionsgroup.com/author/stever/</link>
	<description></description>
	<lastBuildDate>Tue, 07 Jul 2026 23:04:07 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=7.0.5</generator>

<image>
	<url>https://sqlsolutionsgroup.com/wp-content/uploads/2021/01/cropped-SSG_FAVICON0002-32x32.png</url>
	<title>Steve Rezhener, Author at SQL Solutions Group</title>
	<link>https://sqlsolutionsgroup.com/author/stever/</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>How to use PowerShell to get your toolbelt into a Windows Server without a browser</title>
		<link>https://sqlsolutionsgroup.com/how-to-use-powershell-to-get-your-toolbelt-into-a-windows-server-without-a-browser/</link>
		
		<dc:creator><![CDATA[Steve Rezhener]]></dc:creator>
		<pubDate>Tue, 08 Sep 2020 09:54:00 +0000</pubDate>
				<category><![CDATA[SQL Group]]></category>
		<category><![CDATA[#microsftcertifedmaster]]></category>
		<category><![CDATA[#microsftpartner]]></category>
		<category><![CDATA[#SQLAB]]></category>
		<category><![CDATA[#SQlatino]]></category>
		<category><![CDATA[#SQlatinoamerica]]></category>
		<category><![CDATA[#sqldatabase]]></category>
		<category><![CDATA[#sqldeveloper]]></category>
		<category><![CDATA[#SQLgroupie]]></category>
		<category><![CDATA[#sqlimer]]></category>
		<category><![CDATA[#sqlimerbymay]]></category>
		<category><![CDATA[#sqlinjection]]></category>
		<category><![CDATA[#sqlinternals]]></category>
		<category><![CDATA[#sqlite]]></category>
		<category><![CDATA[#sqlite3]]></category>
		<category><![CDATA[#SQLLearning]]></category>
		<category><![CDATA[#SQLMagazine]]></category>
		<category><![CDATA[#sqlmanagementstudio]]></category>
		<category><![CDATA[#sqlmanager]]></category>
		<category><![CDATA[#Sqlmap]]></category>
		<category><![CDATA[#sqlrun]]></category>
		<category><![CDATA[#sqlsaturday2017]]></category>
		<category><![CDATA[#sqlsatvienna]]></category>
		<category><![CDATA[#sqlserver]]></category>
		<category><![CDATA[#SQLserver2012]]></category>
		<category><![CDATA[#sqlserver2014]]></category>
		<category><![CDATA[#sqlserver2017]]></category>
		<category><![CDATA[#sqlserver2022]]></category>
		<category><![CDATA[#SQLServeronLinux]]></category>
		<category><![CDATA[#SQLsolutionsgroup]]></category>
		<category><![CDATA[#SQLTraining]]></category>
		<category><![CDATA[#SQLYog]]></category>
		<category><![CDATA[powershell]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[SQLPASS]]></category>
		<category><![CDATA[SQLSaturday]]></category>
		<category><![CDATA[SSG]]></category>
		<category><![CDATA[Windows Server]]></category>
		<guid isPermaLink="false">https://sqlsolutionsgroup.com/?p=5213</guid>

					<description><![CDATA[<p>Enjoy installing and using the software. Disclaimer This blog post is partially based on https://www.thewindowsclub.com/download-file-using-windows-powershell</p>
<p>The post <a href="https://sqlsolutionsgroup.com/how-to-use-powershell-to-get-your-toolbelt-into-a-windows-server-without-a-browser/">How to use PowerShell to get your toolbelt into a Windows Server without a browser</a> appeared first on <a href="https://sqlsolutionsgroup.com">SQL Solutions Group</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<div class="wp-block-image">
<figure class="aligncenter size-large"><img fetchpriority="high" decoding="async" width="474" height="355" class="wp-image-5214" src="https://sqlsolutionsgroup.com/wp-content/uploads/2020/09/windows-powershell.jpg" alt="How to use PowerShell to get your toolbelt into a Windows Server" srcset="https://sqlsolutionsgroup.com/wp-content/uploads/2020/09/windows-powershell.jpg 474w, https://sqlsolutionsgroup.com/wp-content/uploads/2020/09/windows-powershell-300x225.jpg 300w" sizes="(max-width: 474px) 100vw, 474px" /></figure>
</div>



<h3><strong>Introduction</strong></h3>
<p>This post describes how to use PowerShell to get your favorite toolbelt into a new database environment, your new jump box or VM that is based on a Window Server OS, <em><strong>without</strong></em> using an internet browser.</p>
<p>For me personally, I like to have the same tools everywhere I go. Tools (I often call it a toolbelt) that I know how to use—tools that are making me more productive/efficient, and preferably tools that have a price tag of <em><strong>free</strong></em>.</p>
<p>My favorite toolbelt for SQL Server consists of the following software packages:</p>
<ul>
<li><span style="text-decoration: underline;"><a href="https://www.microsoft.com/en-us/edge">Microsoft Edge Chromium</a></span> (replaces IE and smooths your interaction with the Web and <span style="text-decoration: underline;"><a href="https://docs.microsoft.com/">docs.microsoft.com</a></span>)</li>
<li><a href="https://docs.microsoft.com/en-us/sql/ssms/download-sql-server-management-studio-ssms?view=sql-server-ver15"><span style="text-decoration: underline;">SQL Server Management Studio</span></a> (enables connectivity to SQL Server instance)</li>
<li><a href="https://www.red-gate.com/products/sql-development/sql-search/"><span style="text-decoration: underline;">RedGate SQL Search</span></a> (finds objects or keywords inside procedure and/jobs)</li>
<li><span style="text-decoration: underline;"><a href="https://www.sentryone.com/plan-explorer">SentryOne Plan Explorer</a></span> (gives more in-depth information on a query execution plan)</li>
<li><span style="text-decoration: underline;"><a href="https://www.apexsql.com/sql-tools-refactor.aspx">ApexSQL Refactor</a></span> (makes your code more readable)</li>
</ul>
<h3><strong>Problem</strong></h3>
<p>While I don’t know enough about Linux, I do know enough about Windows. Unfortunately, Windows Server is still shipped with an Internet Explorer (a.k.a. IE), making it the only browser available to you. Even more unfortunate, IE is nothing but a plain pain (a.k.a. PP) to use. IE doesn’t make anything easy, especially when it&#8217;s installed on a server with a corporate group policy (a.k.a. GP) that is making downloads extremely painful.</p>
<p>Try to download anything external to a Windows Server with Internet Explorer and you will see a high level of PP. It’s like this browser is trying to keep you insulated from modern progress by reminding you (Fig #1) what you are not allowed to experience due to “some” security! </p>



<div class="wp-block-image">
<figure class="aligncenter size-large"><img decoding="async" width="1024" height="662" class="wp-image-5215" src="https://sqlsolutionsgroup.com/wp-content/uploads/2020/09/Powershell-1.png" alt="How to use PowerShell to get your toolbelt into a Windows Server without a browser" srcset="https://sqlsolutionsgroup.com/wp-content/uploads/2020/09/Powershell-1.png 1024w, https://sqlsolutionsgroup.com/wp-content/uploads/2020/09/Powershell-1-300x194.png 300w, https://sqlsolutionsgroup.com/wp-content/uploads/2020/09/Powershell-1-768x497.png 768w" sizes="(max-width: 1024px) 100vw, 1024px" />
<figcaption>Figure 1</figcaption>
</figure>
</div>



<h3><strong>Solution</strong></h3>
<p>While you can’t control which internet browser Microsoft ships with Windows Server and it’s a bit difficult to change GP, you completely skip using IE for downloads – introducing PowerShell (a.k.a. PS).</p>
<p>PS cmdlets will let you download anything that you want (<em><strong>your corporate security policies still apply her</strong></em>e). This is how to use PowerShell to add your toolbelt to a new environment, easy-peasy. You don’t need to know much PS syntax and virtually all Windows Servers are shipped with PowerShell, so let’s see how easy it really is.</p>
<p>All you need is to incorporate the following code into a ps1 file and run it. You can use Windows PowerShell ISE (see Fig #2) or VS Code or alternatively you can run line by line from a PowerShell Command Prompt (see Fig #3).</p>
<div id="wpshdo_1" class="wp-synhighlighter-outer"><div id="wpshdt_1" class="wp-synhighlighter-expanded"><table border="0" width="100%"><tr><td align="left" width="80%"><a name="#codesyntax_1"></a><a id="wpshat_1" class="wp-synhighlighter-title" href="#codesyntax_1"  onClick="javascript:wpsh_toggleBlock(1)" title="Click to show/hide code block">Source code</a></td><td align="right"><a href="#codesyntax_1" onClick="javascript:wpsh_code(1)" title="Show code only"><img decoding="async" border="0" style="border: 0 none" src="https://sqlsolutionsgroup.com/wp-content/plugins/wp-synhighlight/themes/default/images/code.png" /></a>&nbsp;<a href="#codesyntax_1" onClick="javascript:wpsh_print(1)" title="Print code"><img decoding="async" border="0" style="border: 0 none" src="https://sqlsolutionsgroup.com/wp-content/plugins/wp-synhighlight/themes/default/images/printer.png" /></a>&nbsp;<a href="https://sqlsolutionsgroup.com/wp-content/plugins/wp-synhighlight/About.html" target="_blank" title="Show plugin information"><img decoding="async" border="0" style="border: 0 none" src="https://sqlsolutionsgroup.com/wp-content/plugins/wp-synhighlight/themes/default/images/info.gif" /></a>&nbsp;</td></tr></table></div><div id="wpshdi_1" class="wp-synhighlighter-inner" style="display: block;"><pre class="powershell" style="font-family:monospace;"><span class="br0">[</span>Net.ServicePointManager<span class="br0">]</span>::SecurityProtocol <span class="sy0">=</span> <span class="br0">[</span>Net.SecurityProtocolType<span class="br0">]</span>::Tls12
<span class="re0">$client</span> <span class="sy0">=</span> <span class="kw1">new-object</span> System.Net.WebClient
&nbsp;
<span class="co1">#test download datasteve image</span>
<span class="co1">#$client.DownloadFile(“https://steverezhener.files.wordpress.com/2019/12/datasteve-sm.jpg?w=107”,“C:\Users\Steve.Rezhener\Pictures\datasteve.jpg”)</span>
&nbsp;
<span class="co1">#download Edge Chromium</span>
<span class="re0">$client</span>.DownloadFile<span class="br0">&#40;</span>“https:<span class="sy0">//</span>dl.delivery.<span class="kw2">mp</span>.microsoft.com<span class="sy0">/</span>filestreamingservice<span class="sy0">/</span>files<span class="sy0">/</span>789ec525<span class="sy0">-</span>0feb<span class="sy0">-</span>4d62<span class="sy0">-</span>a24b<span class="sy0">-</span>99fd15d117e4<span class="sy0">/</span>MicrosoftEdgeEnterpriseX64.msi”<span class="sy0">,</span>“C:\Users\Steve.Rezhener\Downloads\MicrosoftEdgeEnterpriseX64.msi”<span class="br0">&#41;</span>
&nbsp;
<span class="co1">#download SSMS</span>
<span class="re0">$client</span>.DownloadFile<span class="br0">&#40;</span>“https:<span class="sy0">//</span>aka.ms<span class="sy0">/</span>ssmsfullsetup”<span class="sy0">,</span>“C:\Users\Steve.Rezhener\Downloads\ssms<span class="sy0">-</span>setup<span class="sy0">-</span>enu.exe”<span class="br0">&#41;</span>
&nbsp;
<span class="co1">#download Red Gate SQL Search</span>
<span class="re0">$client</span>.DownloadFile<span class="br0">&#40;</span>“https:<span class="sy0">//</span>download.red<span class="sy0">-</span>gate.com<span class="sy0">/</span>SQL_Search.exe”<span class="sy0">,</span>“C:\Users\Steve.Rezhener\Downloads\SQL_Search.exe”<span class="br0">&#41;</span>
&nbsp;
<span class="co1">#download SentryOne Plan Explorer</span>
<span class="re0">$client</span>.DownloadFile<span class="br0">&#40;</span>“https:<span class="sy0">//</span>downloads.sentryone.com<span class="sy0">/</span>downloads<span class="sy0">/</span>sqlsentryplanexplorer<span class="sy0">/</span>x64<span class="sy0">/</span>PlanExplorerInstaller.exe”<span class="sy0">,</span>“C:\Users\Steve.Rezhener\Downloads\PlanExplorerInstaller.exe”<span class="br0">&#41;</span>
&nbsp;
<span class="co1">#download ApexSQL Refactor</span>
<span class="re0">$client</span>.DownloadFile<span class="br0">&#40;</span>“https:<span class="sy0">//</span>www.apexsql.com<span class="sy0">/</span>zips<span class="sy0">/</span>ApexSQLRefactor.exe”<span class="sy0">,</span>“C:\Users\Steve.Rezhener\Downloads\ApexSQLRefactor.exe”<span class="br0">&#41;</span></pre></div></div>



<div class="wp-block-image">
<figure class="aligncenter size-large"><img decoding="async" width="1024" height="359" class="wp-image-5216" src="https://sqlsolutionsgroup.com/wp-content/uploads/2020/09/Powershell-2.png" alt="" srcset="https://sqlsolutionsgroup.com/wp-content/uploads/2020/09/Powershell-2.png 1024w, https://sqlsolutionsgroup.com/wp-content/uploads/2020/09/Powershell-2-300x105.png 300w, https://sqlsolutionsgroup.com/wp-content/uploads/2020/09/Powershell-2-768x269.png 768w" sizes="(max-width: 1024px) 100vw, 1024px" />
<figcaption>Figure 2</figcaption>
</figure>
</div>



<div class="wp-block-image">
<figure class="aligncenter size-large"><img loading="lazy" decoding="async" width="1024" height="292" class="wp-image-5217" src="https://sqlsolutionsgroup.com/wp-content/uploads/2020/09/Powershell-3.png" alt="" srcset="https://sqlsolutionsgroup.com/wp-content/uploads/2020/09/Powershell-3.png 1024w, https://sqlsolutionsgroup.com/wp-content/uploads/2020/09/Powershell-3-300x86.png 300w, https://sqlsolutionsgroup.com/wp-content/uploads/2020/09/Powershell-3-768x219.png 768w" sizes="(max-width: 1024px) 100vw, 1024px" />
<figcaption>Figure 3</figcaption>
</figure>
</div>



<p>If you are using Windows PowerShell ISE, just click the play button, wait for about 30 seconds and enjoy my toolbelt (see Fig #4) or feel free to change my code to download anything else you need and bypass the IE.</p>



<div class="wp-block-image">
<figure class="aligncenter size-large"><img loading="lazy" decoding="async" width="760" height="311" class="wp-image-5219" src="https://sqlsolutionsgroup.com/wp-content/uploads/2020/09/Powershell-4.png" alt="" srcset="https://sqlsolutionsgroup.com/wp-content/uploads/2020/09/Powershell-4.png 760w, https://sqlsolutionsgroup.com/wp-content/uploads/2020/09/Powershell-4-300x123.png 300w" sizes="(max-width: 760px) 100vw, 760px" />
<figcaption>Figure 4</figcaption>
</figure>
</div>



<p class="wp-block-paragraph">Enjoy installing and using the software.</p>



<p class="wp-block-paragraph"><strong>Disclaimer</strong></p>



<p class="wp-block-paragraph">This blog post is partially based on <a href="https://www.thewindowsclub.com/download-file-using-windows-powershell">https://www.thewindowsclub.com/download-file-using-windows-powershell</a></p>
<p>The post <a href="https://sqlsolutionsgroup.com/how-to-use-powershell-to-get-your-toolbelt-into-a-windows-server-without-a-browser/">How to use PowerShell to get your toolbelt into a Windows Server without a browser</a> appeared first on <a href="https://sqlsolutionsgroup.com">SQL Solutions Group</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>How to monitor database backups and integrity with SentryOne SQL Sentry custom advisory conditions</title>
		<link>https://sqlsolutionsgroup.com/monitoring-database-backups-with-sqlsentry/</link>
					<comments>https://sqlsolutionsgroup.com/monitoring-database-backups-with-sqlsentry/#comments</comments>
		
		<dc:creator><![CDATA[Steve Rezhener]]></dc:creator>
		<pubDate>Thu, 03 Sep 2020 07:54:38 +0000</pubDate>
				<category><![CDATA[SQL Group]]></category>
		<category><![CDATA[SQL Server]]></category>
		<category><![CDATA[#microsftcertifedmaster]]></category>
		<category><![CDATA[#microsftpartner]]></category>
		<category><![CDATA[#SQLAB]]></category>
		<category><![CDATA[#SQlatino]]></category>
		<category><![CDATA[#SQlatinoamerica]]></category>
		<category><![CDATA[#sqldatabase]]></category>
		<category><![CDATA[#sqldeveloper]]></category>
		<category><![CDATA[#SQLgroupie]]></category>
		<category><![CDATA[#sqlimer]]></category>
		<category><![CDATA[#sqlimerbymay]]></category>
		<category><![CDATA[#sqlinjection]]></category>
		<category><![CDATA[#sqlinternals]]></category>
		<category><![CDATA[#sqlite]]></category>
		<category><![CDATA[#sqlite3]]></category>
		<category><![CDATA[#SQLLearning]]></category>
		<category><![CDATA[#SQLMagazine]]></category>
		<category><![CDATA[#sqlmanagementstudio]]></category>
		<category><![CDATA[#sqlmanager]]></category>
		<category><![CDATA[#Sqlmap]]></category>
		<category><![CDATA[#sqlrun]]></category>
		<category><![CDATA[#sqlsaturday2017]]></category>
		<category><![CDATA[#sqlsatvienna]]></category>
		<category><![CDATA[#sqlserver]]></category>
		<category><![CDATA[#SQLserver2012]]></category>
		<category><![CDATA[#sqlserver2014]]></category>
		<category><![CDATA[#sqlserver2017]]></category>
		<category><![CDATA[#sqlserver2022]]></category>
		<category><![CDATA[#SQLServeronLinux]]></category>
		<category><![CDATA[#SQLsolutionsgroup]]></category>
		<category><![CDATA[#SQLTraining]]></category>
		<category><![CDATA[#SQLYog]]></category>
		<category><![CDATA[backups]]></category>
		<category><![CDATA[monitor]]></category>
		<category><![CDATA[SentryOne]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[SQL Sentry]]></category>
		<category><![CDATA[SQLPASS]]></category>
		<category><![CDATA[SQLSaturday]]></category>
		<category><![CDATA[SSG]]></category>
		<guid isPermaLink="false">https://sqlsolutionsgroup.com/?p=5176</guid>

					<description><![CDATA[<p>This blog post discusses how to leverage SentryOne’s SQL Sentry product to monitor database backups and integrity checks. At SSG, we</p>
<p>The post <a href="https://sqlsolutionsgroup.com/monitoring-database-backups-with-sqlsentry/">How to monitor database backups and integrity with SentryOne SQL Sentry custom advisory conditions</a> appeared first on <a href="https://sqlsolutionsgroup.com">SQL Solutions Group</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<div class="wp-block-image">
<figure class="alignleft is-resized"><img loading="lazy" decoding="async" class="wp-image-5177" src="https://sqlsolutionsgroup.com/wp-content/uploads/2020/08/sqlsentry1.jpg" alt="Monitor database backups" width="400" height="81" srcset="https://sqlsolutionsgroup.com/wp-content/uploads/2020/08/sqlsentry1.jpg 400w, https://sqlsolutionsgroup.com/wp-content/uploads/2020/08/sqlsentry1-300x61.jpg 300w" sizes="(max-width: 400px) 100vw, 400px" /></figure>
</div>

<div class="wp-block-image is-style-default"> </div>
<h3> </h3>
<p>&nbsp;</p>
<h3><strong>Introduction</strong></h3>
<p>This blog post discusses how to leverage <a href="https://www.sentryone.com/">SentryOne&#8217;s</a> SQL Sentry product to monitor database backups and integrity checks.</p>
<p>At SSG, we are big fans of SentryOne and have been a partner for many years. If you are not familiar with the product, it is a Performance Monitoring solution for SQL Server, as well as Analysis Services, Azure SQL Database, SQL Server on Amazon RDS and more. </p>
<p>That being said, this blog post is not about why SentryOne is a great product, but rather provides a solution to a problem using custom advisory conditions. </p>
<h3><strong>Problem</strong></h3>
<p>One of the basic responsibilities of any DBA is making sure that backups and database integrity checks are in-place. While we can monitor jobs that run these for failures, a more sure way is to get the SQL Server metadata about the last backup and last checkdb. In some cases, backups are running through third party software or from a centralized system, so a job would not even exist. And what we really want to know is &#8220;when was the last successful backup.&#8221; The same is true for database integrity checks.</p>
<p>Without SentryOne, we have a couple of options:</p>
<ul>
<li>Create a job using the dbatools PowerShell module (which we are also big fans of) and use the cmdlets <span style="text-decoration: underline;"><a href="https://docs.dbatools.io/#Get-DbaDbBackupHistory">Get-DbaDbBackupHistory</a></span>  and <span style="text-decoration: underline;"><a href="https://docs.dbatools.io/#Get-DbaLastGoodCheckDb">Get-DbaLastGoodCheckDb</a></span> for integrity checks. </li>
<li>Query <span style="text-decoration: underline;"><a href="https://docs.microsoft.com/en-us/sql/relational-databases/system-tables/backupset-transact-sql?view=sql-server-ver15">msdb.dbo.backupset</a></span> table (taking latest backup_finish_date column) for backup history and DATABASEPROPERTYEX (‘dbname’, ‘LastGoodCheckDbTime’) for integrity checks.  </li>
</ul>
<p>Needless to say, those two options are both a bit cumbersome. Additionally, we would need to store this data, so we can see history.</p>
<h3><strong>Solution</strong></h3>
<p>While SentryOne comes with more than 85 built-in advisory conditions, it does not include these two items. The good news is, it’s super easy to add your own conditions.</p>
<p>Advisory Conditions allow us to create conditions using queries against the SentryOne repository as well as against other database(s) and several other options. Since SentryOne is already collecting the information we need for these two conditions, we can just query the repository database. </p>
<p>The following query will be used to pull the required data from the repository:</p>
<div id="wpshdo_2" class="wp-synhighlighter-outer"><div id="wpshdt_2" class="wp-synhighlighter-expanded"><table border="0" width="100%"><tr><td align="left" width="80%"><a name="#codesyntax_2"></a><a id="wpshat_2" class="wp-synhighlighter-title" href="#codesyntax_2"  onClick="javascript:wpsh_toggleBlock(2)" title="Click to show/hide code block">Source code</a></td><td align="right"><a href="#codesyntax_2" onClick="javascript:wpsh_code(2)" title="Show code only"><img decoding="async" border="0" style="border: 0 none" src="https://sqlsolutionsgroup.com/wp-content/plugins/wp-synhighlight/themes/default/images/code.png" /></a>&nbsp;<a href="#codesyntax_2" onClick="javascript:wpsh_print(2)" title="Print code"><img decoding="async" border="0" style="border: 0 none" src="https://sqlsolutionsgroup.com/wp-content/plugins/wp-synhighlight/themes/default/images/printer.png" /></a>&nbsp;<a href="https://sqlsolutionsgroup.com/wp-content/plugins/wp-synhighlight/About.html" target="_blank" title="Show plugin information"><img decoding="async" border="0" style="border: 0 none" src="https://sqlsolutionsgroup.com/wp-content/plugins/wp-synhighlight/themes/default/images/info.gif" /></a>&nbsp;</td></tr></table></div><div id="wpshdi_2" class="wp-synhighlighter-inner" style="display: block;"><pre class="tsql" style="font-family:monospace;"><span class="kw1">SELECT</span> esc.<span class="me1">objectname</span> <span class="sy0">+</span> <span class="st0">'.'</span> <span class="sy0">+</span> db.<span class="me1">name</span> <span class="kw1">AS</span> server_database
, <span class="kw2">DATEDIFF</span><span class="br0">&#40;</span><span class="kw1">DAY</span>,<span class="kw2">MAX</span><span class="br0">&#40;</span>LastDbccCheckDbTime<span class="br0">&#41;</span>,<span class="kw2">GETDATE</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="kw1">AS</span> LastDbccCheckinDays
, <span class="kw2">DATEDIFF</span><span class="br0">&#40;</span><span class="kw1">DAY</span>,<span class="kw2">MAX</span><span class="br0">&#40;</span>LastBackupTime<span class="br0">&#41;</span>, <span class="kw2">GETDATE</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="kw1">AS</span> LastBackupinDays
<span class="kw1">FROM</span>
    Device
    <span class="sy0">JOIN</span> EventSourceConnection esc <span class="kw1">ON</span>
        esc.<span class="me1">DeviceID</span> <span class="sy0">=</span> Device.<span class="me1">ID</span>
    <span class="sy0">JOIN</span> PerformanceAnalysisSqlDatabase db <span class="kw1">ON</span>
        db.<span class="me1">EventSourceConnectionID</span> <span class="sy0">=</span> esc.<span class="me1">ID</span>
    <span class="sy0">JOIN</span> PerformanceAnalysisSqlFile f <span class="kw1">ON</span>
        f.<span class="me1">EventSourceConnectionID</span> <span class="sy0">=</span> esc.<span class="me1">ID</span>
<span class="kw1">WHERE</span> <span class="nu0">1</span><span class="sy0">=</span><span class="nu0">1</span>
<span class="sy0">AND</span> f.<span class="me1">lastbackuptype</span> <span class="sy0">=</span> <span class="st0">'D'</span>
and db.<span class="me1">name</span> <span class="sy0">NOT</span> <span class="sy0">IN</span> <span class="br0">&#40;</span><span class="st0">'tempdb'</span>,<span class="st0">'distribution'</span><span class="br0">&#41;</span>
<span class="kw1">GROUP</span> <span class="kw1">BY</span> esc.<span class="me1">objectname</span>
, db.<span class="me1">name</span></pre></div></div>
<p>The following steps outline how to add this query as a custom condition across all monitored servers:</p>
<p>From the  Navigator, expand the Advisory Conditions node and open the Condition List, then click on Create Advisory Condition. </p>
<p><a href="https://sqlsolutionsgroup.com/wp-content/uploads/2020/08/sqlsentry2.png"><img loading="lazy" decoding="async" class="alignnone wp-image-5178 size-full" src="https://sqlsolutionsgroup.com/wp-content/uploads/2020/08/sqlsentry2.png" alt="Monitor database backups" width="1024" height="735" srcset="https://sqlsolutionsgroup.com/wp-content/uploads/2020/08/sqlsentry2.png 1024w, https://sqlsolutionsgroup.com/wp-content/uploads/2020/08/sqlsentry2-300x215.png 300w, https://sqlsolutionsgroup.com/wp-content/uploads/2020/08/sqlsentry2-768x551.png 768w" sizes="(max-width: 1024px) 100vw, 1024px" /></a></p>
<ol>
<li>Add a name (Track missing full database backups/Track missing database checkdbs)</li>
<li>Click on +</li>
<li>Select Add Numeric Comparison</li>
<li>Select Repository Query</li>
<li>Add the query</li>
<li>Select Any</li>
<li>Select Is Greater than</li>
<li>Select Explicit Value</li>
<li>Type 7 (or whatever threshold you want to set).</li>
<li>Save the condition</li>
</ol>
<p><a href="https://sqlsolutionsgroup.com/wp-content/uploads/2020/08/sqlsentry3.png"><img decoding="async" class="wp-image-5179 size-full" src="https://sqlsolutionsgroup.com/wp-content/uploads/2020/08/sqlsentry3.png" alt="" width="800" srcset="https://sqlsolutionsgroup.com/wp-content/uploads/2020/08/sqlsentry3.png 877w, https://sqlsolutionsgroup.com/wp-content/uploads/2020/08/sqlsentry3-300x146.png 300w, https://sqlsolutionsgroup.com/wp-content/uploads/2020/08/sqlsentry3-768x375.png 768w" sizes="(max-width: 877px) 100vw, 877px" /></a></p>
<p>Alternatively, you can just download the two files from the following github public repository and import them: </p>
<p><span style="text-decoration: underline;"><a href="https://github.com/steverezhener/S1-custom-conditions">Custom Conditions</a></span></p>
<p>Your condition list should get updated once you download and import the conditions. At this point you can configure whatever actions you want as  you would for any other condition in SentryOne. These steps should make it easy to monitor database backups using SentryOne.</p>
<p><a href="https://sqlsolutionsgroup.com/wp-content/uploads/2020/08/sqlsentry4.png"><img decoding="async" class="size-full wp-image-5180 alignleft" src="https://sqlsolutionsgroup.com/wp-content/uploads/2020/08/sqlsentry4.png" alt="" width="800" srcset="https://sqlsolutionsgroup.com/wp-content/uploads/2020/08/sqlsentry4.png 917w, https://sqlsolutionsgroup.com/wp-content/uploads/2020/08/sqlsentry4-300x165.png 300w, https://sqlsolutionsgroup.com/wp-content/uploads/2020/08/sqlsentry4-768x422.png 768w" sizes="(max-width: 917px) 100vw, 917px" /></a></p>
<p>&nbsp;</p>
<p><strong>Disclaimer:</strong></p>
<p>This blog post is partially based on the following resources:</p>
<p><a href="https://www.sentryone.com/blog/query-database-growth-over-time-from-your-sentryone-sql-sentry-database">https://www.sentryone.com/blog/query-database-growth-over-time-from-your-sentryone-sql-sentry-database</a></p>
<p><a href="https://www.mssqltips.com/sqlservertip/1601/script-to-retrieve-sql-server-database-backup-history-and-no-backups/">https://www.mssqltips.com/sqlservertip/1601/script-to-retrieve-sql-server-database-backup-history-and-no-backups/</a></p>
<p><span style="text-decoration: underline;"><a href="https://thomaslarock.com/2018/05/using-databasepropertyex-to-find-last-good-dbcc-checkdb-time/">https://thomaslarock.com/2018/05/using-databasepropertyex-to-find-last-good-dbcc-checkdb-time/</a>.</span></p><p>The post <a href="https://sqlsolutionsgroup.com/monitoring-database-backups-with-sqlsentry/">How to monitor database backups and integrity with SentryOne SQL Sentry custom advisory conditions</a> appeared first on <a href="https://sqlsolutionsgroup.com">SQL Solutions Group</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://sqlsolutionsgroup.com/monitoring-database-backups-with-sqlsentry/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
			</item>
		<item>
		<title>Using Extended Event Session (XE) to track queries going against Always On AG primary</title>
		<link>https://sqlsolutionsgroup.com/using-extended-event-session/</link>
		
		<dc:creator><![CDATA[Steve Rezhener]]></dc:creator>
		<pubDate>Thu, 16 Jul 2020 09:34:00 +0000</pubDate>
				<category><![CDATA[SQL Group]]></category>
		<category><![CDATA[SQL Server]]></category>
		<category><![CDATA[#microsftcertifedmaster]]></category>
		<category><![CDATA[#microsftpartner]]></category>
		<category><![CDATA[#SQLAB]]></category>
		<category><![CDATA[#SQlatino]]></category>
		<category><![CDATA[#SQlatinoamerica]]></category>
		<category><![CDATA[#sqldatabase]]></category>
		<category><![CDATA[#sqldeveloper]]></category>
		<category><![CDATA[#SQLgroupie]]></category>
		<category><![CDATA[#sqlimer]]></category>
		<category><![CDATA[#sqlimerbymay]]></category>
		<category><![CDATA[#sqlinjection]]></category>
		<category><![CDATA[#sqlinternals]]></category>
		<category><![CDATA[#sqlite]]></category>
		<category><![CDATA[#sqlite3]]></category>
		<category><![CDATA[#SQLLearning]]></category>
		<category><![CDATA[#SQLMagazine]]></category>
		<category><![CDATA[#sqlmanagementstudio]]></category>
		<category><![CDATA[#sqlmanager]]></category>
		<category><![CDATA[#Sqlmap]]></category>
		<category><![CDATA[#sqlrun]]></category>
		<category><![CDATA[#sqlsaturday2017]]></category>
		<category><![CDATA[#sqlsatvienna]]></category>
		<category><![CDATA[#sqlserver]]></category>
		<category><![CDATA[#SQLserver2012]]></category>
		<category><![CDATA[#sqlserver2014]]></category>
		<category><![CDATA[#sqlserver2017]]></category>
		<category><![CDATA[#sqlserver2022]]></category>
		<category><![CDATA[#SQLServeronLinux]]></category>
		<category><![CDATA[#SQLsolutionsgroup]]></category>
		<category><![CDATA[#SQLTraining]]></category>
		<category><![CDATA[#SQLYog]]></category>
		<category><![CDATA[AG]]></category>
		<category><![CDATA[Always On]]></category>
		<category><![CDATA[availability groups]]></category>
		<category><![CDATA[Extended Events]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[SQLPASS]]></category>
		<category><![CDATA[SQLSaturday]]></category>
		<category><![CDATA[SSG]]></category>
		<guid isPermaLink="false">https://sqlsolutionsgroup.com/?p=5135</guid>

					<description><![CDATA[<p>The post <a href="https://sqlsolutionsgroup.com/using-extended-event-session/">Using Extended Event Session (XE) to track queries going against Always On AG primary</a> appeared first on <a href="https://sqlsolutionsgroup.com">SQL Solutions Group</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p><a href="https://sqlsolutionsgroup.com/wp-content/uploads/2020/07/XE-AG.jpg"><img loading="lazy" decoding="async" class="aligncenter wp-image-5136 size-full" src="https://sqlsolutionsgroup.com/wp-content/uploads/2020/07/XE-AG.jpg" alt="Using Extended Event Session with AG" width="728" height="546" srcset="https://sqlsolutionsgroup.com/wp-content/uploads/2020/07/XE-AG.jpg 728w, https://sqlsolutionsgroup.com/wp-content/uploads/2020/07/XE-AG-300x225.jpg 300w" sizes="(max-width: 728px) 100vw, 728px" /></a></p>
<p><em>Using Extended Event Session, once we add filters, we can see specifics – queries that are hitting a specific database on Server A (primary) from a specific server (and many excluding the monitoring software).</em></p>
<h3><strong>Introduction</strong></h3>
<p>The Always On Availability Group (aka AG) feature in SQL Server provides a great HADR (high-availability and disaster recovery) solution. This HADR solution can also be used to alleviate the pain from a single database server. AG allows the user to add new servers to offload reporting needs (read replicas) without any prior domain knowledge.</p>
<p>To start with a new read replica, you would need a new Database Server and AG as a data synchronization mechanism (synchronous mode for time sensitive needs and asynchronous mode for everything else). Read replica provides a database on a new server that will help to lift the pressure from a single Server A (AG primary) by making Server B (AG secondary/read replica) available for all the read queries.</p>
<h3><strong>Problem</strong></h3>
<p>AG is relying on a connection string directive called <strong>Read-Intent only</strong> which instructs SQL Server to redirect all the calls to a read replica. Unfortunately, all the existing connections were defined before AG introduction, so what do we do now? How would we identify all the read queries that need a connection string change? Again, without changing connection strings, all the existing queries will still be hitting Server A, hence AG by itself would not solve the problem.</p>
<h3><strong>Solution</strong></h3>
<p>Introducing Extended Event sessions (aka XE session). XE is essentially a replacement for SQL Profiler, which enables us to see everything that is hitting the SQL Server while offering better interface and scripting capabilities. Once we add filters, we can see specifics – queries that are hitting a specific database on Server A (primary) from a specific server (and many excluding the monitoring software).</p>
<p>The following script creates a new XE session that ignores system queries, includes queries that are going against a Database called Database from a server called DW while excluding queries from SentryOne monitoring software.</p>
<div id="wpshdo_3" class="wp-synhighlighter-outer"><div id="wpshdt_3" class="wp-synhighlighter-expanded"><table border="0" width="100%"><tr><td align="left" width="80%"><a name="#codesyntax_3"></a><a id="wpshat_3" class="wp-synhighlighter-title" href="#codesyntax_3"  onClick="javascript:wpsh_toggleBlock(3)" title="Click to show/hide code block">Source code</a></td><td align="right"><a href="#codesyntax_3" onClick="javascript:wpsh_code(3)" title="Show code only"><img decoding="async" border="0" style="border: 0 none" src="https://sqlsolutionsgroup.com/wp-content/plugins/wp-synhighlight/themes/default/images/code.png" /></a>&nbsp;<a href="#codesyntax_3" onClick="javascript:wpsh_print(3)" title="Print code"><img decoding="async" border="0" style="border: 0 none" src="https://sqlsolutionsgroup.com/wp-content/plugins/wp-synhighlight/themes/default/images/printer.png" /></a>&nbsp;<a href="https://sqlsolutionsgroup.com/wp-content/plugins/wp-synhighlight/About.html" target="_blank" title="Show plugin information"><img decoding="async" border="0" style="border: 0 none" src="https://sqlsolutionsgroup.com/wp-content/plugins/wp-synhighlight/themes/default/images/info.gif" /></a>&nbsp;</td></tr></table></div><div id="wpshdi_3" class="wp-synhighlighter-inner" style="display: block;"><pre class="tsql" style="font-family:monospace;"><span class="kw1">CREATE</span> EVENT <span class="kw1">SESSION</span> <span class="br0">[</span>DW going against <span class="kw1">PRIMARY</span><span class="br0">]</span> <span class="kw1">ON</span> SERVER 
<span class="kw1">ADD</span> EVENT sqlserver.<span class="me1">sql_batch_starting</span><span class="br0">&#40;</span>
    <span class="kw1">ACTION</span><span class="br0">&#40;</span>sqlserver.<span class="me1">client_app_name</span>,sqlserver.<span class="me1">client_hostname</span>,sqlserver.<span class="me1">database_name</span>,sqlserver.<span class="me1">nt_username</span>,sqlserver.<span class="me1">sql_text</span>,sqlserver.<span class="me1">username</span><span class="br0">&#41;</span>
&nbsp;
<span class="kw1">WHERE</span> <span class="br0">&#40;</span><span class="br0">[</span>package0<span class="br0">]</span>.<span class="br0">[</span>equal_boolean<span class="br0">]</span><span class="br0">&#40;</span><span class="br0">[</span>sqlserver<span class="br0">]</span>.<span class="br0">[</span>is_system<span class="br0">]</span>,<span class="br0">&#40;</span><span class="nu0">0</span><span class="br0">&#41;</span><span class="br0">&#41;</span> 
&nbsp;
<span class="sy0">AND</span> <span class="br0">[</span>sqlserver<span class="br0">]</span>.<span class="br0">[</span>like_i_sql_unicode_string<span class="br0">]</span><span class="br0">&#40;</span><span class="br0">[</span>sqlserver<span class="br0">]</span>.<span class="br0">[</span>sql_text<span class="br0">]</span>,N<span class="st0">'%OLTP_Database%'</span><span class="br0">&#41;</span> 
&nbsp;
<span class="sy0">AND</span> <span class="br0">[</span>sqlserver<span class="br0">]</span>.<span class="br0">[</span>equal_i_sql_unicode_string<span class="br0">]</span><span class="br0">&#40;</span><span class="br0">[</span>sqlserver<span class="br0">]</span>.<span class="br0">[</span>client_hostname<span class="br0">]</span>,N<span class="st0">'DW'</span><span class="br0">&#41;</span> 
&nbsp;
<span class="sy0">AND</span> <span class="br0">[</span>sqlserver<span class="br0">]</span>.<span class="br0">[</span>not_equal_i_sql_unicode_string<span class="br0">]</span><span class="br0">&#40;</span><span class="br0">[</span>sqlserver<span class="br0">]</span>.<span class="br0">[</span>client_app_name<span class="br0">]</span>,N<span class="st0">'SentryOne 20.0-Server'</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>
&nbsp;
<span class="kw1">WITH</span> <span class="br0">&#40;</span>MAX_MEM<span class="sy0">OR</span>Y<span class="sy0">=</span>4096 KB,EVENT_RETENTION_MODE<span class="sy0">=ALL</span>OW_S<span class="sy0">IN</span>GLE_EVENT_LOSS,MAX_DISPATCH_LATENCY<span class="sy0">=</span>5 SECONDS,MAX_EVENT_SIZE<span class="sy0">=</span>0 KB,MEM<span class="sy0">OR</span>Y_PARTITION_MODE<span class="sy0">=</span>PER_CPU
,TRACK_CAUSALITY<span class="sy0">=</span><span class="kw1">ON</span>,STARTUP_STATE<span class="sy0">=</span><span class="kw1">OFF</span><span class="br0">&#41;</span>
GO</pre></div></div>
<p><strong>Disclaimer</strong></p>
<p>This blog post is partially based on the following sources:</p>
<p><a href="https://docs.microsoft.com/en-us/sql/database-engine/availability-groups/windows/always-on-availability-groups-sql-server?view=sql-server-ver15#:~:text=The%20Always%20On%20availability%20groups%20feature%20is%20a,a%20set%20of%20user%20databases%20for%20an%20enterprise.">https://docs.microsoft.com/en-us/sql/database-engine/availability-groups/windows/always-on-availability-groups-sql-server</a></p>
<p><a href="https://docs.microsoft.com/en-us/sql/relational-databases/extended-events/sql-server-extended-events-sessions?view=sql-server-ver15#:~:text=%20The%20following%20aspects%20of%20an%20Extended%20Events,of%20an%20Extended%20Events%20session%2C%20such...%20More%20">https://docs.microsoft.com/en-us/sql/relational-databases/extended-events/sql-server-extended-events-sessions</a></p>
<p>The post <a href="https://sqlsolutionsgroup.com/using-extended-event-session/">Using Extended Event Session (XE) to track queries going against Always On AG primary</a> appeared first on <a href="https://sqlsolutionsgroup.com">SQL Solutions Group</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Inspecting Power BI performance</title>
		<link>https://sqlsolutionsgroup.com/power-bi-performance/</link>
		
		<dc:creator><![CDATA[Steve Rezhener]]></dc:creator>
		<pubDate>Wed, 17 Jun 2020 18:23:00 +0000</pubDate>
				<category><![CDATA[SQL Group]]></category>
		<category><![CDATA[#microsftcertifedmaster]]></category>
		<category><![CDATA[#microsftpartner]]></category>
		<category><![CDATA[#SQLAB]]></category>
		<category><![CDATA[#SQlatino]]></category>
		<category><![CDATA[#SQlatinoamerica]]></category>
		<category><![CDATA[#sqldatabase]]></category>
		<category><![CDATA[#sqldeveloper]]></category>
		<category><![CDATA[#SQLgroupie]]></category>
		<category><![CDATA[#sqlimer]]></category>
		<category><![CDATA[#sqlimerbymay]]></category>
		<category><![CDATA[#sqlinjection]]></category>
		<category><![CDATA[#sqlinternals]]></category>
		<category><![CDATA[#sqlite]]></category>
		<category><![CDATA[#sqlite3]]></category>
		<category><![CDATA[#SQLLearning]]></category>
		<category><![CDATA[#SQLMagazine]]></category>
		<category><![CDATA[#sqlmanagementstudio]]></category>
		<category><![CDATA[#sqlmanager]]></category>
		<category><![CDATA[#Sqlmap]]></category>
		<category><![CDATA[#sqlrun]]></category>
		<category><![CDATA[#sqlsaturday2017]]></category>
		<category><![CDATA[#sqlsatvienna]]></category>
		<category><![CDATA[#sqlserver]]></category>
		<category><![CDATA[#SQLserver2012]]></category>
		<category><![CDATA[#sqlserver2014]]></category>
		<category><![CDATA[#sqlserver2017]]></category>
		<category><![CDATA[#sqlserver2022]]></category>
		<category><![CDATA[#SQLServeronLinux]]></category>
		<category><![CDATA[#SQLsolutionsgroup]]></category>
		<category><![CDATA[#SQLTraining]]></category>
		<category><![CDATA[#SQLYog]]></category>
		<category><![CDATA[How To]]></category>
		<category><![CDATA[Power BI]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[SQLPASS]]></category>
		<category><![CDATA[SQLSaturday]]></category>
		<category><![CDATA[SSG]]></category>
		<guid isPermaLink="false">https://sqlsolutionsgroup.com/?p=5088</guid>

					<description><![CDATA[<p>The post <a href="https://sqlsolutionsgroup.com/power-bi-performance/">Inspecting Power BI performance</a> appeared first on <a href="https://sqlsolutionsgroup.com">SQL Solutions Group</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<h4><strong>Introduction</strong></h4>
<p>This blog post is going to discuss inspection of Power BI performance when you use Power BI Gateway to push data to PowerBI.com service.</p>
<p>I am going to assume here that you are not new to PowerBI. I am also going to assume that you skipped PowerBI Report Server (which requires a hefty Software Assurance $$$) and settled with a more cost-effective way to run your pbix files using PowerBI.com service ($10 for Power BI Pro or $5K+ for PowerBI Premium). My last assumption would be that you are using Power BI Gateway to push your data to PowerBI.com service.</p>
<h4><strong>Problem</strong></h4>
<p><em><strong>Customer</strong></em>: Please allow me to see Execution Logs for Power BI.</p>
<p><em><strong>Me</strong></em>: Looks like you are using a Power BI Gateway. Let me find it.</p>
<p>Let’s start with how we normally visualize performance: We would look for data collected in a run-time. On-premise solutions like IIS would have log files and reporting platform like SSRS would have some database records that we can review. While I am very familiar with ingesting and analyzing IIS log files and building reports on SSRS by exposing the data collected in <a href="https://docs.microsoft.com/en-us/sql/reporting-services/report-server/report-server-executionlog-and-the-executionlog3-view?view=sql-server-ver15">ExecutionLog3 view</a> under a ReportServer database, I was very skeptical that Microsoft will expose anything for PowerBI.com. After all, PowerBI.com is Microsoft internal infrastructure.</p>
<p>I guess I was proven wrong. Of course Microsoft is not showing us how bad PowerBI was hammered to process the report or how much time it took to render a report, but Microsoft still collects enough data to weed out the worst performing queries.</p>
<h4><strong>Solution</strong></h4>
<p>Ironically, not only this is possible, but Microsoft went an extra mile and created <a href="https://download.microsoft.com/download/D/A/1/DA1FDDB8-6DA8-4F50-B4D0-18019591E182/GatewayPerformanceMonitoring.pbit">Performance BI template</a> for Power BI performance. This is quite awesome.</p>
<p>So what do we need to do to inspect PowerBI performance? We would need to:</p>
<ol>
<li>Enable performance logging by setting both QueryExecutionReportOn and SystemCounterReportOn to True inside <em>GatewayCore.dll.config</em> xml file (you are going to need write/read permission to make changes in C:\Program Files\On-premises data gateway\ folder)</li>
</ol>
<p><img decoding="async" src="https://steverezhener.files.wordpress.com/2020/06/image-1.png?w=963" /></p>
<p>2. Set ReportFilePath variable to a shared folder that is more accessible and better managed than a local C drive (Power BI Gateway default)</p>
<p><img decoding="async" src="https://steverezhener.files.wordpress.com/2020/06/image-6.png?w=709" /></p>
<p>&nbsp;</p>
<p>3. Restart Power BI Gateway service (or upgrade if possible)</p>
<p><img decoding="async" src="https://steverezhener.files.wordpress.com/2020/06/image.png?w=639" /></p>
<p>4. Download the <a href="https://download.microsoft.com/download/D/A/1/DA1FDDB8-6DA8-4F50-B4D0-18019591E182/GatewayPerformanceMonitoring.pbit">Gateway Performance PBI template</a></p>
<p>5. Import previously downloaded template (Select <strong>File &gt; Import &gt; Power BI template</strong> from within Power BI Desktop)</p>
<p><img decoding="async" src="https://docs.microsoft.com/en-us/power-bi/create-reports/media/desktop-templates/desktop-templates-04.png" alt="Import a template" /></p>
<p>&nbsp;</p>
<p>6. Change folder path to point to log files (if applicable)</p>
<p><img decoding="async" src="https://docs.microsoft.com/en-us/data-integration/gateway/media/service-gateway-performance/gateway-folder-path-pop-up.png" alt="Pop-up for the folder path" /></p>
<p>7. Enjoy it</p>
<p><img decoding="async" src="https://steverezhener.files.wordpress.com/2020/06/image-5.png?w=1024" /></p>
<p>8. Enable additional logging inside On-premises data gateway (if more logging is required)</p>
<p><img loading="lazy" decoding="async" class="alignnone" src="https://docs.microsoft.com/en-us/data-integration/gateway/media/service-gateway-performance/additional-logging.png" alt="Power BI performance" width="640" height="648" /></p>
<h4><strong>Disclaimer</strong></h4>
<p>This blog post is partially based on the following Microsoft article – <a href="https://docs.microsoft.com/en-us/data-integration/gateway/service-gateway-performance">https://docs.microsoft.com/en-us/data-integration/gateway/service-gateway-performance</a>.</p>
<p>The post <a href="https://sqlsolutionsgroup.com/power-bi-performance/">Inspecting Power BI performance</a> appeared first on <a href="https://sqlsolutionsgroup.com">SQL Solutions Group</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>How to ensure that all the SSRS features are working while using Always On Availability Groups OR have an RSExecRole as a default</title>
		<link>https://sqlsolutionsgroup.com/rsexecrole-default/</link>
		
		<dc:creator><![CDATA[Steve Rezhener]]></dc:creator>
		<pubDate>Fri, 15 May 2020 07:35:00 +0000</pubDate>
				<category><![CDATA[SQL Group]]></category>
		<category><![CDATA[#microsftcertifedmaster]]></category>
		<category><![CDATA[#microsftpartner]]></category>
		<category><![CDATA[#SQLAB]]></category>
		<category><![CDATA[#SQlatino]]></category>
		<category><![CDATA[#SQlatinoamerica]]></category>
		<category><![CDATA[#sqldatabase]]></category>
		<category><![CDATA[#sqldeveloper]]></category>
		<category><![CDATA[#SQLgroupie]]></category>
		<category><![CDATA[#sqlimer]]></category>
		<category><![CDATA[#sqlimerbymay]]></category>
		<category><![CDATA[#sqlinjection]]></category>
		<category><![CDATA[#sqlinternals]]></category>
		<category><![CDATA[#sqlite]]></category>
		<category><![CDATA[#sqlite3]]></category>
		<category><![CDATA[#SQLLearning]]></category>
		<category><![CDATA[#SQLMagazine]]></category>
		<category><![CDATA[#sqlmanagementstudio]]></category>
		<category><![CDATA[#sqlmanager]]></category>
		<category><![CDATA[#Sqlmap]]></category>
		<category><![CDATA[#sqlrun]]></category>
		<category><![CDATA[#sqlsaturday2017]]></category>
		<category><![CDATA[#sqlsatvienna]]></category>
		<category><![CDATA[#sqlserver]]></category>
		<category><![CDATA[#SQLserver2012]]></category>
		<category><![CDATA[#sqlserver2014]]></category>
		<category><![CDATA[#sqlserver2017]]></category>
		<category><![CDATA[#sqlserver2022]]></category>
		<category><![CDATA[#SQLServeronLinux]]></category>
		<category><![CDATA[#SQLsolutionsgroup]]></category>
		<category><![CDATA[#SQLTraining]]></category>
		<category><![CDATA[#SQLYog]]></category>
		<category><![CDATA[availability groups]]></category>
		<category><![CDATA[How To]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[SQLPASS]]></category>
		<category><![CDATA[SQLSaturday]]></category>
		<category><![CDATA[SSG]]></category>
		<category><![CDATA[SSRS]]></category>
		<guid isPermaLink="false">https://sqlsolutionsgroup.com/?p=5001</guid>

					<description><![CDATA[<p>The post <a href="https://sqlsolutionsgroup.com/rsexecrole-default/">How to ensure that all the SSRS features are working while using Always On Availability Groups OR have an RSExecRole as a default</a> appeared first on <a href="https://sqlsolutionsgroup.com">SQL Solutions Group</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<h3><strong>Introduction</strong></h3>
<p><a href="https://sqlsolutionsgroup.com/wp-content/uploads/2020/05/thebeachboys.jpg"><img loading="lazy" decoding="async" class="wp-image-5003 size-medium alignleft" src="https://sqlsolutionsgroup.com/wp-content/uploads/2020/05/thebeachboys-295x300.jpg" alt="SSRS and RSExecRole" width="295" height="300" srcset="https://sqlsolutionsgroup.com/wp-content/uploads/2020/05/thebeachboys-295x300.jpg 295w, https://sqlsolutionsgroup.com/wp-content/uploads/2020/05/thebeachboys-768x780.jpg 768w, https://sqlsolutionsgroup.com/wp-content/uploads/2020/05/thebeachboys.jpg 816w" sizes="(max-width: 295px) 100vw, 295px" /></a></p>
<p>This blog post addresses SSRS on Always On and RSExecRole. To make sure I’m staying laser focused on this topic, I need to cover some fundamentals.</p>
<p><strong>SSRS installation (SQL Server 2017 and later)</strong></p>
<p>Starting from SQL Server 2017, Microsoft decided to separate SSRS from a SQL Server installation container (ISO). Keeping the pros and cons of this change aside, that means that Microsoft decided some customers would not need SSRS, and adding a separate step to install it would effectively block an accidental “next-next” type of installation. If a separate SSRS installer is triggered, it will add all the necessary SSRS plumbing to SQL Server database engine, such as ReportServer and ReportServerTemp databases to support SSRS, database roles. It will also add many other pieces that are not related to SQL Server, such as web service, web application, etc…</p>
<p><a href="https://docs.microsoft.com/en-us/sql/reporting-services/install-windows/install-reporting-services?view=sql-server-ver15">https://docs.microsoft.com/en-us/sql/reporting-services/install-windows/install-reporting-services?view=sql-server-ver15</a></p>
<p><strong>Always On Availability Groups (a.k.a. AG)</strong></p>
<p>Always On Availability Groups is the latest and greatest Microsoft HADR (High Availability and Disaster Recovery) solution to keep SQL Server running in case of failure. AlwaysOn Availability groups allows to enroll databases into a group that would be kept in sync between the active server (a.k.a. primary, supporting both read and write) database and passive (a.k.a. replica, supporting read only) databases.</p>
<p><a href="https://docs.microsoft.com/en-us/sql/database-engine/availability-groups/windows/always-on-availability-groups-sql-server?view=sql-server-ver15">https://docs.microsoft.com/en-us/sql/database-engine/availability-groups/windows/always-on-availability-groups-sql-server?view=sql-server-ver15</a></p>
<p><strong>SSRS Subscriptions</strong></p>
<p>SSRS subscription is a saved configuration that is designed to simplify report rendering and delivery. You choose a report, format, schedule and a method of delivery, and suddenly your users are more self sufficient and you have more free time.</p>
<p><a href="https://docs.microsoft.com/en-us/sql/reporting-services/subscriptions/subscriptions-and-delivery-reporting-services?view=sql-server-ver15">https://docs.microsoft.com/en-us/sql/reporting-services/subscriptions/subscriptions-and-delivery-reporting-services?view=sql-server-ver15</a></p>
<h3><strong>Problem</strong></h3>
<p>Once you have mission critical databases included in availability groups it makes a total sense to add both ReportServer (storage for datasources, datasets, reports, etc…) and ReportServerTempDB databases (TempDB for SSRS)  as well. This way in case of a disaster recovery, your data-sources (OLTP databases for example) and reporting platform (SSRS) are up and running at the same time without any manual steps.</p>
<p>With Always On Availability Groups (a.k.a. AlwaysOn AG), both the data and schema are constantly (synchronous mode) or almost constantly (asynchronous mode) in-sync, but there is one user requirement. Always On requires same logins (stored in master that is not part of AG) and SQL Server Agent jobs (stored in msdb that is not part of AG). While it might look like that adding ReportServer and ReportServerTemp databases to AG would be enough to have SSRS fully supported for HADR, unfortunately that is not entirely true.</p>
<p>With both SSRS databases on AG, most of the functionality is available, so SSRS Report Portal will serve reports (records from the datasource, datasets, and catalog tables) and obey the security mechanism (users, policies, role tables), but SSRS subscription will suddenly stop working (despite the subscription table being in-sync). Any existing SSRS subscriptions will stop working regardless if SSRS GUID job (unfortunately, Microsoft never got to make SSRS jobs user-friendly) is enabled or not. Trying to create a new SSRS subscription will be greeted with a very cryptic error message (Fig #1).</p>
<p><img loading="lazy" decoding="async" class="alignnone" src="https://steverezhener.files.wordpress.com/2020/05/image.png?w=1024" alt="RSExecRole" width="1024" height="375" /></p>
<p>Little known fact about SSRS: Outside of ReportServer database, SSRS is not only dependent on jobs and logins, but also on a custom database role called RSExecRole that is created by the SSRS installer. This role needs to exist in both master and msdb and since both of their databases are normally not in AG (per server and not in-sync) and SSRS is not actually installed on the replica, SSRS subscriptions would no longer work.</p>
<h3><strong>Solution</strong></h3>
<p>The solution is fairly easy and will involve following Microsoft documentation that is designed for a scenario of moving SSRS from one server to another.</p>
<p><a href="https://docs.microsoft.com/en-us/sql/reporting-services/security/create-the-rsexecrole?view=sql-server-ver15ecrole?view=sql-server-ver15">https://docs.microsoft.com/en-us/sql/reporting-services/security/create-the-rsexecrole?view=sql-server-ver15ecrole?view=sql-server-ver15</a></p>
<p>The following code will create RSExecRole database role in both master and msdb databases and will grant all the necessary permissions needed for SSRS subscription functionality.</p>
<div id="wpshdo_4" class="wp-synhighlighter-outer"><div id="wpshdt_4" class="wp-synhighlighter-expanded"><table border="0" width="100%"><tr><td align="left" width="80%"><a name="#codesyntax_4"></a><a id="wpshat_4" class="wp-synhighlighter-title" href="#codesyntax_4"  onClick="javascript:wpsh_toggleBlock(4)" title="Click to show/hide code block">Source code</a></td><td align="right"><a href="#codesyntax_4" onClick="javascript:wpsh_code(4)" title="Show code only"><img decoding="async" border="0" style="border: 0 none" src="https://sqlsolutionsgroup.com/wp-content/plugins/wp-synhighlight/themes/default/images/code.png" /></a>&nbsp;<a href="#codesyntax_4" onClick="javascript:wpsh_print(4)" title="Print code"><img decoding="async" border="0" style="border: 0 none" src="https://sqlsolutionsgroup.com/wp-content/plugins/wp-synhighlight/themes/default/images/printer.png" /></a>&nbsp;<a href="https://sqlsolutionsgroup.com/wp-content/plugins/wp-synhighlight/About.html" target="_blank" title="Show plugin information"><img decoding="async" border="0" style="border: 0 none" src="https://sqlsolutionsgroup.com/wp-content/plugins/wp-synhighlight/themes/default/images/info.gif" /></a>&nbsp;</td></tr></table></div><div id="wpshdi_4" class="wp-synhighlighter-inner" style="display: block;"><pre class="tsql" style="font-family:monospace;"><span class="kw1">USE</span> master;
GO
<span class="kw1">IF</span> <span class="sy0">NOT</span> <span class="sy0">EXISTS</span> <span class="br0">&#40;</span><span class="kw1">SELECT</span> 1 <span class="kw1">FROM</span> sys.<span class="me1">database_principals</span> <span class="kw1">WHERE</span> <span class="br0">[</span>type<span class="br0">]</span> <span class="sy0">=</span> <span class="st0">'R'</span> <span class="sy0">AND</span> <span class="br0">[</span>name<span class="br0">]</span> <span class="sy0">=</span> <span class="st0">'RSExecRole'</span><span class="br0">&#41;</span> <span class="kw1">BEGIN</span>
    <span class="kw1">CREATE</span> <span class="kw1">ROLE</span> <span class="br0">[</span>RSExecRole<span class="br0">]</span>;
<span class="kw1">END</span>
<span class="kw1">GRANT</span> <span class="kw1">EXECUTE</span> <span class="kw1">ON</span> dbo.<span class="me1">xp_sqlagent_enum_jobs</span> <span class="kw1">TO</span> <span class="br0">[</span>RSExecRole<span class="br0">]</span>;
<span class="kw1">GRANT</span> <span class="kw1">EXECUTE</span> <span class="kw1">ON</span> dbo.<span class="me1">xp_sqlagent_is_starting</span> <span class="kw1">TO</span> <span class="br0">[</span>RSExecRole<span class="br0">]</span>;
<span class="kw1">GRANT</span> <span class="kw1">EXECUTE</span> <span class="kw1">ON</span> dbo.<span class="me1">xp_sqlagent_notify</span> <span class="kw1">TO</span> <span class="br0">[</span>RSExecRole<span class="br0">]</span>;
GO
<span class="kw1">USE</span> msdb;
GO
<span class="kw1">IF</span> <span class="sy0">NOT</span> <span class="sy0">EXISTS</span> <span class="br0">&#40;</span><span class="kw1">SELECT</span> 1 <span class="kw1">FROM</span> sys.<span class="me1">database_principals</span> <span class="kw1">WHERE</span> <span class="br0">[</span>type<span class="br0">]</span> <span class="sy0">=</span> <span class="st0">'R'</span> <span class="sy0">AND</span> <span class="br0">[</span>name<span class="br0">]</span> <span class="sy0">=</span> <span class="st0">'RSExecRole'</span><span class="br0">&#41;</span> <span class="kw1">BEGIN</span>
    <span class="kw1">CREATE</span> <span class="kw1">ROLE</span> <span class="br0">[</span>RSExecRole<span class="br0">]</span>;
<span class="kw1">END</span>
<span class="kw1">GRANT</span> <span class="kw1">EXECUTE</span> <span class="kw1">ON</span> dbo.<span class="kw3">SP_ADD_CATEGORY</span> <span class="kw1">TO</span> <span class="br0">[</span>RSExecRole<span class="br0">]</span>;
<span class="kw1">GRANT</span> <span class="kw1">EXECUTE</span> <span class="kw1">ON</span> dbo.<span class="kw3">SP_ADD_JOB</span> <span class="kw1">TO</span> <span class="br0">[</span>RSExecRole<span class="br0">]</span>;
<span class="kw1">GRANT</span> <span class="kw1">EXECUTE</span> <span class="kw1">ON</span> dbo.<span class="kw3">SP_ADD_JOBSCHEDULE</span> <span class="kw1">TO</span> <span class="br0">[</span>RSExecRole<span class="br0">]</span>;
<span class="kw1">GRANT</span> <span class="kw1">EXECUTE</span> <span class="kw1">ON</span> dbo.<span class="kw3">SP_ADD_JOBSERVER</span> <span class="kw1">TO</span> <span class="br0">[</span>RSExecRole<span class="br0">]</span>;
<span class="kw1">GRANT</span> <span class="kw1">EXECUTE</span> <span class="kw1">ON</span> dbo.<span class="kw3">SP_ADD_JOBSTEP</span> <span class="kw1">TO</span> <span class="br0">[</span>RSExecRole<span class="br0">]</span>;
<span class="kw1">GRANT</span> <span class="kw1">EXECUTE</span> <span class="kw1">ON</span> dbo.<span class="kw3">SP_DELETE_JOB</span> <span class="kw1">TO</span> <span class="br0">[</span>RSExecRole<span class="br0">]</span>;
<span class="kw1">GRANT</span> <span class="kw1">EXECUTE</span> <span class="kw1">ON</span> dbo.<span class="kw3">SP_HELP_CATEGORY</span> <span class="kw1">TO</span> <span class="br0">[</span>RSExecRole<span class="br0">]</span>;
<span class="kw1">GRANT</span> <span class="kw1">EXECUTE</span> <span class="kw1">ON</span> dbo.<span class="kw3">SP_HELP_JOB</span> <span class="kw1">TO</span> <span class="br0">[</span>RSExecRole<span class="br0">]</span>;
<span class="kw1">GRANT</span> <span class="kw1">EXECUTE</span> <span class="kw1">ON</span> dbo.<span class="kw3">SP_HELP_JOBSCHEDULE</span> <span class="kw1">TO</span> <span class="br0">[</span>RSExecRole<span class="br0">]</span>;
<span class="kw1">GRANT</span> <span class="kw1">EXECUTE</span> <span class="kw1">ON</span> dbo.<span class="me1">sp_verify_job_identifiers</span> <span class="kw1">TO</span> <span class="br0">[</span>RSExecRole<span class="br0">]</span>;
<span class="kw1">GRANT</span> <span class="kw1">SELECT</span> <span class="kw1">ON</span> dbo.<span class="me1">syscategories</span> <span class="kw1">TO</span> <span class="br0">[</span>RSExecRole<span class="br0">]</span>;
<span class="kw1">GRANT</span> <span class="kw1">SELECT</span> <span class="kw1">ON</span> dbo.<span class="me1">sysjobs</span> <span class="kw1">TO</span> <span class="br0">[</span>RSExecRole<span class="br0">]</span>;
GO</pre></div></div>
<p>Of course it would be nice if <strong>RSExecRole</strong> database role and permissions were created by default, regardless of the SSRS installation, by making it part of the “system” objects. That would be a small price to pay for a happier DBA. Wouldn’t it be nice? As the Beach Boys would sing it, “you know its gonna make it much better”!</p>
<p>The post <a href="https://sqlsolutionsgroup.com/rsexecrole-default/">How to ensure that all the SSRS features are working while using Always On Availability Groups OR have an RSExecRole as a default</a> appeared first on <a href="https://sqlsolutionsgroup.com">SQL Solutions Group</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Linked Server in SQL Server: the good, the bad, and the way to make it perfect!</title>
		<link>https://sqlsolutionsgroup.com/linked-server-in-sql-server/</link>
					<comments>https://sqlsolutionsgroup.com/linked-server-in-sql-server/#comments</comments>
		
		<dc:creator><![CDATA[Steve Rezhener]]></dc:creator>
		<pubDate>Tue, 07 Apr 2020 15:43:00 +0000</pubDate>
				<category><![CDATA[SQL Group]]></category>
		<category><![CDATA[SQL Server]]></category>
		<category><![CDATA[#microsftcertifedmaster]]></category>
		<category><![CDATA[#microsftpartner]]></category>
		<category><![CDATA[#SQLAB]]></category>
		<category><![CDATA[#SQlatino]]></category>
		<category><![CDATA[#SQlatinoamerica]]></category>
		<category><![CDATA[#sqldatabase]]></category>
		<category><![CDATA[#sqldeveloper]]></category>
		<category><![CDATA[#SQLgroupie]]></category>
		<category><![CDATA[#sqlimer]]></category>
		<category><![CDATA[#sqlimerbymay]]></category>
		<category><![CDATA[#sqlinjection]]></category>
		<category><![CDATA[#sqlinternals]]></category>
		<category><![CDATA[#sqlite]]></category>
		<category><![CDATA[#sqlite3]]></category>
		<category><![CDATA[#SQLLearning]]></category>
		<category><![CDATA[#SQLMagazine]]></category>
		<category><![CDATA[#sqlmanagementstudio]]></category>
		<category><![CDATA[#sqlmanager]]></category>
		<category><![CDATA[#Sqlmap]]></category>
		<category><![CDATA[#sqlrun]]></category>
		<category><![CDATA[#sqlsaturday2017]]></category>
		<category><![CDATA[#sqlsatvienna]]></category>
		<category><![CDATA[#sqlserver]]></category>
		<category><![CDATA[#SQLserver2012]]></category>
		<category><![CDATA[#sqlserver2014]]></category>
		<category><![CDATA[#sqlserver2017]]></category>
		<category><![CDATA[#sqlserver2022]]></category>
		<category><![CDATA[#SQLServeronLinux]]></category>
		<category><![CDATA[#SQLsolutionsgroup]]></category>
		<category><![CDATA[#SQLTraining]]></category>
		<category><![CDATA[#SQLYog]]></category>
		<category><![CDATA[How To]]></category>
		<category><![CDATA[linked server]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[SQLPASS]]></category>
		<category><![CDATA[SQLSaturday]]></category>
		<category><![CDATA[SSG]]></category>
		<guid isPermaLink="false">https://sqlsolutionsgroup.com/?p=4656</guid>

					<description><![CDATA[<p>The post <a href="https://sqlsolutionsgroup.com/linked-server-in-sql-server/">Linked Server in SQL Server: the good, the bad, and the way to make it perfect!</a> appeared first on <a href="https://sqlsolutionsgroup.com">SQL Solutions Group</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<h3><a href="https://sqlsolutionsgroup.com/wp-content/uploads/2020/04/Linked0.gif"><img loading="lazy" decoding="async" class="aligncenter wp-image-4657 size-full" src="https://sqlsolutionsgroup.com/wp-content/uploads/2020/04/Linked0.gif" alt="linked servers in SQL Server" width="429" height="357" /></a></h3>
<p><em>One of the all-time best performing posts on our blog is from Randy Knight and outlines <span style="text-decoration: underline;"><a href="https://sqlsolutionsgroup.com/using-linked-servers-the-right-way/">how to use Linked Servers the right way</a></span>. In this post from Steve Rezhener, he shows how OPENQUERY can make all the difference with Linked Servers.</em></p>
<h3><strong>Introduction (the good)</strong></h3>
<p>If you are not familiar with a linked server concept in SQL Server, don’t worry, you probably haven&#8217;t needed it yet. You are fortunate to source all your data needs from a single database server, and that is fine. Or maybe you are consuming your SQL Server needs from Azure Single Database or AWS RDS (both public cloud solutions don’t support linked server out of the box).</p>
<p>Most likely this is going to change (Azure VM and AWS EC2 have full support) and you will have to join data between multiple database servers, or even between different RDBMS systems. For example: All the transactional sales data is stored in SQL Server, but all the analytical sales data is stored on another SQL Server server (this could even be MySQL).</p>
<p>This is where Linked Server comes in handy, especially at the data discovery phase. When building a prototype needs to happen quickly and there is no time to adhere to the best practices, Linked Server can be the answer.</p>
<p>This blog post outlines the pros and cons of linked servers in SQL Server as well as how to reduce the cons of using an OPENQUERY.</p>
<h3>Linked Servers Basics</h3>
<p><a href="https://docs.microsoft.com/en-us/sql/relational-databases/linked-servers/linked-servers-database-engine?view=sql-server-ver15">According to Microsoft</a>, linked servers enable the SQL Server Database Engine and Azure SQL Database Managed Instance to read data from the remote data sources and execute commands against the remote database servers (for example, OLE DB data sources) outside of the instance of SQL Server. </p>
<p>Linked Server is a pure convenience feature. With very little to no code changes, you can suddenly join multiple tables between local and remote/cloud servers. For example, let’s use WideWorldImporters transactional database</p>
<figure id="attachment_4658" aria-describedby="caption-attachment-4658" style="width: 1024px" class="wp-caption aligncenter"><a href="https://sqlsolutionsgroup.com/wp-content/uploads/2020/04/linked1.png"><img loading="lazy" decoding="async" class="wp-image-4658 size-full" src="https://sqlsolutionsgroup.com/wp-content/uploads/2020/04/linked1.png" alt="" width="1024" height="359" srcset="https://sqlsolutionsgroup.com/wp-content/uploads/2020/04/linked1.png 1024w, https://sqlsolutionsgroup.com/wp-content/uploads/2020/04/linked1-300x105.png 300w, https://sqlsolutionsgroup.com/wp-content/uploads/2020/04/linked1-768x269.png 768w" sizes="(max-width: 1024px) 100vw, 1024px" /></a><figcaption id="caption-attachment-4658" class="wp-caption-text">Figure 1</figcaption></figure>
<p>Linked Server effectively removes the need for a solution that will move and synchronize the data. You just setup a Linked Server (see Fig #2) and add a Linked Server reference in front of the three-part naming convention (see Fig #3). That&#8217;s all. A small price to pay for lots of convenience.</p>
<figure class="wp-block-gallery columns-1 is-cropped">
<figure id="attachment_4659" aria-describedby="caption-attachment-4659" style="width: 688px" class="wp-caption aligncenter"><a href="https://sqlsolutionsgroup.com/wp-content/uploads/2020/04/linked2.png"><img loading="lazy" decoding="async" class="wp-image-4659 size-full" src="https://sqlsolutionsgroup.com/wp-content/uploads/2020/04/linked2.png" alt="Linked Server in SQL Server" width="688" height="623" srcset="https://sqlsolutionsgroup.com/wp-content/uploads/2020/04/linked2.png 688w, https://sqlsolutionsgroup.com/wp-content/uploads/2020/04/linked2-300x272.png 300w" sizes="(max-width: 688px) 100vw, 688px" /></a><figcaption id="caption-attachment-4659" class="wp-caption-text">Figure 2</figcaption></figure>
<p>&nbsp;</p>
<figure id="attachment_4660" aria-describedby="caption-attachment-4660" style="width: 1024px" class="wp-caption aligncenter"><a href="https://sqlsolutionsgroup.com/wp-content/uploads/2020/04/linked3.png"><img loading="lazy" decoding="async" class="wp-image-4660 size-full" src="https://sqlsolutionsgroup.com/wp-content/uploads/2020/04/linked3.png" alt="" width="1024" height="392" srcset="https://sqlsolutionsgroup.com/wp-content/uploads/2020/04/linked3.png 1024w, https://sqlsolutionsgroup.com/wp-content/uploads/2020/04/linked3-300x115.png 300w, https://sqlsolutionsgroup.com/wp-content/uploads/2020/04/linked3-768x294.png 768w" sizes="(max-width: 1024px) 100vw, 1024px" /></a><figcaption id="caption-attachment-4660" class="wp-caption-text">Figure 3</figcaption></figure>
<h3><strong>Problem (the bad)</strong></h3>
<p>While the Linked Server feature makes it easy to join tables between two or more different servers, it’s not free and it comes with a price tag: performance overhead. While joining a few small tables might not add noticeable pressure to the server, joining 3-5 fairly large remote tables might introduce locking and blocking and increase the run-time from seconds to minutes.</p>
<p>The main problem occurs when you run queries against a remote server, which is not healthy. When SQL Server runs a query with Linked Server, it will use the least optimal execution plan due to lack of knowledge of those remote tables. Meaning, your local SQL Server is clueless on remote table indexes and statistics, so it might use an incorrect joining mechanism and might be grossly inefficient.</p>
<p>For example, if you had to join all January 2013 orders between OLTP and OLAP tables and compare revenue per product while showing the five top contributors, we might build the following query (see Fig #4) to achieve that goal:</p>
<figure id="attachment_4661" aria-describedby="caption-attachment-4661" style="width: 1024px" class="wp-caption aligncenter"><a href="https://sqlsolutionsgroup.com/wp-content/uploads/2020/04/Linked4.png"><img loading="lazy" decoding="async" class="wp-image-4661 size-full" src="https://sqlsolutionsgroup.com/wp-content/uploads/2020/04/Linked4.png" alt="" width="1024" height="498" srcset="https://sqlsolutionsgroup.com/wp-content/uploads/2020/04/Linked4.png 1024w, https://sqlsolutionsgroup.com/wp-content/uploads/2020/04/Linked4-300x146.png 300w, https://sqlsolutionsgroup.com/wp-content/uploads/2020/04/Linked4-768x374.png 768w" sizes="(max-width: 1024px) 100vw, 1024px" /></a><figcaption id="caption-attachment-4661" class="wp-caption-text">Figure 4</figcaption></figure>
<p>Reviewing Statistics IO (see Fig #5) and execution plan details (see Fig #6), we see:</p>
<figure id="attachment_4662" aria-describedby="caption-attachment-4662" style="width: 1024px" class="wp-caption aligncenter"><a href="https://sqlsolutionsgroup.com/wp-content/uploads/2020/04/Linked5.png"><img loading="lazy" decoding="async" class="wp-image-4662 size-full" src="https://sqlsolutionsgroup.com/wp-content/uploads/2020/04/Linked5.png" alt="" width="1024" height="177" srcset="https://sqlsolutionsgroup.com/wp-content/uploads/2020/04/Linked5.png 1024w, https://sqlsolutionsgroup.com/wp-content/uploads/2020/04/Linked5-300x52.png 300w, https://sqlsolutionsgroup.com/wp-content/uploads/2020/04/Linked5-768x133.png 768w" sizes="(max-width: 1024px) 100vw, 1024px" /></a><figcaption id="caption-attachment-4662" class="wp-caption-text">Figure 5</figcaption></figure>
<p>&nbsp;</p>
<figure id="attachment_4663" aria-describedby="caption-attachment-4663" style="width: 1024px" class="wp-caption aligncenter"><a href="https://sqlsolutionsgroup.com/wp-content/uploads/2020/04/Linked6.png"><img loading="lazy" decoding="async" class="wp-image-4663 size-full" src="https://sqlsolutionsgroup.com/wp-content/uploads/2020/04/Linked6.png" alt="" width="1024" height="200" srcset="https://sqlsolutionsgroup.com/wp-content/uploads/2020/04/Linked6.png 1024w, https://sqlsolutionsgroup.com/wp-content/uploads/2020/04/Linked6-300x59.png 300w, https://sqlsolutionsgroup.com/wp-content/uploads/2020/04/Linked6-768x150.png 768w" sizes="(max-width: 1024px) 100vw, 1024px" /></a><figcaption id="caption-attachment-4663" class="wp-caption-text">Figure 6</figcaption></figure>
<p><span style="font-size: inherit;">As you might notice (far right), 93% of the query execution cost goes to a “mysterious” remote query.</span></p>
</figure>
<h3><strong>Solution (a way to make it perfect)</strong></h3>
<p>One of the easiest ways to fix performance problems with a linked server is to run it via OPENQUERY.</p>
<p>What is OPENQUERY? <span style="text-decoration: underline;"><a href="https://docs.microsoft.com/en-us/sql/t-sql/functions/openquery-transact-sql?view=sql-server-ver15">According to Microsoft</a></span>, OPENQUERY executes the specified pass-through query on the specified linked server. This server is an OLE DB data source. We can reference OPENQUERY in the FROM clause of a query as if it were a table name. We can also reference OPENQUERY as the target table of an INSERT, UPDATE, or DELETE statement. This is subject to the capabilities of the OLE DB provider. Although the query may return multiple result sets, OPENQUERY returns only the first one. </p>
<p>One of the main advantages of OPENQUERY is remote execution. This  means the local server sends the query to the remote server with knowledge of those remote tables that are now local to the query. By the way, remote execution also enables the use of native syntax of the remote server, so you can take advantage of other RDBMS system performance tricks.</p>
<p>Here is how our original query will look with an OPENQUERY (see Fig #7). It’s still using the same linked server, but it happens indirectly now with an  OPENQUERY.</p>
<figure id="attachment_4664" aria-describedby="caption-attachment-4664" style="width: 1024px" class="wp-caption aligncenter"><a href="https://sqlsolutionsgroup.com/wp-content/uploads/2020/04/Linked7.png"><img loading="lazy" decoding="async" class="wp-image-4664 size-full" src="https://sqlsolutionsgroup.com/wp-content/uploads/2020/04/Linked7.png" alt="Linked Server in SQL Server" width="1024" height="573" srcset="https://sqlsolutionsgroup.com/wp-content/uploads/2020/04/Linked7.png 1024w, https://sqlsolutionsgroup.com/wp-content/uploads/2020/04/Linked7-300x168.png 300w, https://sqlsolutionsgroup.com/wp-content/uploads/2020/04/Linked7-768x430.png 768w" sizes="(max-width: 1024px) 100vw, 1024px" /></a><figcaption id="caption-attachment-4664" class="wp-caption-text">Figure 7</figcaption></figure>
<p>When reviewing Statistics IO (see Fig #8) and execution plan details (see Fig #9), we now see: </p>
<figure id="attachment_4665" aria-describedby="caption-attachment-4665" style="width: 1024px" class="wp-caption aligncenter"><a href="https://sqlsolutionsgroup.com/wp-content/uploads/2020/04/Linked8.png"><img loading="lazy" decoding="async" class="wp-image-4665 size-full" src="https://sqlsolutionsgroup.com/wp-content/uploads/2020/04/Linked8.png" alt="" width="1024" height="166" srcset="https://sqlsolutionsgroup.com/wp-content/uploads/2020/04/Linked8.png 1024w, https://sqlsolutionsgroup.com/wp-content/uploads/2020/04/Linked8-300x49.png 300w, https://sqlsolutionsgroup.com/wp-content/uploads/2020/04/Linked8-768x125.png 768w" sizes="(max-width: 1024px) 100vw, 1024px" /></a><figcaption id="caption-attachment-4665" class="wp-caption-text">Figure 8</figcaption></figure>
<p>&nbsp;</p>
<figure id="attachment_4666" aria-describedby="caption-attachment-4666" style="width: 1024px" class="wp-caption aligncenter"><a href="https://sqlsolutionsgroup.com/wp-content/uploads/2020/04/Linked9.png"><img loading="lazy" decoding="async" class="wp-image-4666 size-full" src="https://sqlsolutionsgroup.com/wp-content/uploads/2020/04/Linked9.png" alt="" width="1024" height="224" srcset="https://sqlsolutionsgroup.com/wp-content/uploads/2020/04/Linked9.png 1024w, https://sqlsolutionsgroup.com/wp-content/uploads/2020/04/Linked9-300x66.png 300w, https://sqlsolutionsgroup.com/wp-content/uploads/2020/04/Linked9-768x168.png 768w" sizes="(max-width: 1024px) 100vw, 1024px" /></a><figcaption id="caption-attachment-4666" class="wp-caption-text">Figure 9</figcaption></figure>
<p>Let’s compare Statistics IO and execution plans to see the differences between direct query linked server usage vs. an OPENQUERY linked server.</p>
<p>The most noticeable differences are:</p>
<ol>
<li>WorkFile reads in Statistics IO (see Fig #10)</li>
<li>Remote Query 93% cost vs. most distributed cost in Execution Plan (see Fig #11) and partially replaced with Remote Scans.</li>
</ol>
<figure id="attachment_4667" aria-describedby="caption-attachment-4667" style="width: 1024px" class="wp-caption aligncenter"><a href="https://sqlsolutionsgroup.com/wp-content/uploads/2020/04/Linked10.png"><img loading="lazy" decoding="async" class="wp-image-4667 size-full" src="https://sqlsolutionsgroup.com/wp-content/uploads/2020/04/Linked10.png" alt="Linked Server in SQL Server" width="1024" height="547" srcset="https://sqlsolutionsgroup.com/wp-content/uploads/2020/04/Linked10.png 1024w, https://sqlsolutionsgroup.com/wp-content/uploads/2020/04/Linked10-300x160.png 300w, https://sqlsolutionsgroup.com/wp-content/uploads/2020/04/Linked10-768x410.png 768w" sizes="(max-width: 1024px) 100vw, 1024px" /></a><figcaption id="caption-attachment-4667" class="wp-caption-text">Figure 10</figcaption></figure>
<h3> </h3>
<h3>Why Does It Work?</h3>
<p>The main reason OPENQUERY will usually perform better is knowledge of the table in terms of indexes and stats, knowledge that a direct linked server doesn’t have.</p>
<p>As you can see, we have managed to cut the run-time from 22 seconds (using direct link server) down to 2 seconds (using OPENQUERY). Additionally, we can add indexes specific to the query to make OPENQUERY even faster.</p>
<h3><strong>Disclaimer</strong></h3>
<p>Since nothing is certain in this life other than taxes and death, your mileage may vary (“YMMV”). Please test it (preferably using DBCC FREEPROCCACHE) prior to deployment. In addition the query above that reduced run-time by 11 times, I also scored a drastic performance gain by using OPENQUERY in one of the clients. In that example, replacing all three direct linked server references reduced run-time by 10 times, to just a few seconds.</p>
<p>The only caveat with OPENQUERY, since it can’t accept parameters, are the use of dynamic SQL and “fighting the quotes” – making sure to escape the single quotes that are internally used by a SQL Server to identify literal, i.e. text.</p>
<p>The post <a href="https://sqlsolutionsgroup.com/linked-server-in-sql-server/">Linked Server in SQL Server: the good, the bad, and the way to make it perfect!</a> appeared first on <a href="https://sqlsolutionsgroup.com">SQL Solutions Group</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://sqlsolutionsgroup.com/linked-server-in-sql-server/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
			</item>
		<item>
		<title>Data Governance – your ultimate stored procedure to get a record count from any table and compare</title>
		<link>https://sqlsolutionsgroup.com/get-a-record-count/</link>
		
		<dc:creator><![CDATA[Steve Rezhener]]></dc:creator>
		<pubDate>Thu, 05 Mar 2020 09:34:19 +0000</pubDate>
				<category><![CDATA[SQL Group]]></category>
		<category><![CDATA[#microsftcertifedmaster]]></category>
		<category><![CDATA[#microsftpartner]]></category>
		<category><![CDATA[#SQLAB]]></category>
		<category><![CDATA[#SQlatino]]></category>
		<category><![CDATA[#SQlatinoamerica]]></category>
		<category><![CDATA[#sqldatabase]]></category>
		<category><![CDATA[#sqldeveloper]]></category>
		<category><![CDATA[#SQLgroupie]]></category>
		<category><![CDATA[#sqlimer]]></category>
		<category><![CDATA[#sqlimerbymay]]></category>
		<category><![CDATA[#sqlinjection]]></category>
		<category><![CDATA[#sqlinternals]]></category>
		<category><![CDATA[#sqlite]]></category>
		<category><![CDATA[#sqlite3]]></category>
		<category><![CDATA[#SQLLearning]]></category>
		<category><![CDATA[#SQLMagazine]]></category>
		<category><![CDATA[#sqlmanagementstudio]]></category>
		<category><![CDATA[#sqlmanager]]></category>
		<category><![CDATA[#Sqlmap]]></category>
		<category><![CDATA[#sqlrun]]></category>
		<category><![CDATA[#sqlsaturday2017]]></category>
		<category><![CDATA[#sqlsatvienna]]></category>
		<category><![CDATA[#sqlserver]]></category>
		<category><![CDATA[#SQLserver2012]]></category>
		<category><![CDATA[#sqlserver2014]]></category>
		<category><![CDATA[#sqlserver2017]]></category>
		<category><![CDATA[#sqlserver2022]]></category>
		<category><![CDATA[#SQLServeronLinux]]></category>
		<category><![CDATA[#SQLsolutionsgroup]]></category>
		<category><![CDATA[#SQLTraining]]></category>
		<category><![CDATA[#SQLYog]]></category>
		<category><![CDATA[data governance]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[SQLPASS]]></category>
		<category><![CDATA[SQLSaturday]]></category>
		<category><![CDATA[SSG]]></category>
		<category><![CDATA[stored procedures]]></category>
		<guid isPermaLink="false">https://sqlsolutionsgroup.com/?p=4595</guid>

					<description><![CDATA[<p>The post <a href="https://sqlsolutionsgroup.com/get-a-record-count/">Data Governance – your ultimate stored procedure to get a record count from any table and compare</a> appeared first on <a href="https://sqlsolutionsgroup.com">SQL Solutions Group</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p><strong>Introduction</strong></p>
<p><a href="https://searchdatamanagement.techtarget.com/definition/data-governance" target="_blank" rel="noopener noreferrer"><span style="text-decoration: underline;">Data Governance</span></a> plays an important role in building a successful data-driven company as it helps business users to trust the data. While a typical Data Analytics project starts with identifying all relevant transactional sources of information, building your Data Warehouse according to business needs and feeding (and converting) the data as often as possible, one can argue that without operational reports alerting on a lag between the two systems, your Data Analytics function is doomed. No matter how great your Data Warehouse is, if the users are constantly complaining about bad data, your Data Warehouse project days are numbered.</p>
<p>I am assuming that you followed best practices and isolated your company analytical server (OLAP) from your transactional server (OLTP). You also set up an ongoing replication in near real-time. As much as business users are happy to analyze all the historical data (great for trending analysis that requires volume of data), they would also love to see real-time data (great for an e-commerce company that is coming up with new products). But how do you ensure your dependent tables are in-sync?</p>
<h3><strong>Problem</strong></h3>
<p>How do you compare data between source and destination tables using a repeatable process? One of the first reporting needs in a Data Governance report is comparing counts to identify any missing records. Having a code that allows to get a record count from any table anywhere (local/remote server) will make it easy.</p>
<h3><strong>Solution</strong></h3>
<p>We are going to build a reusable stored procedure that could help in a Data Governance Report to capture record counts between source and destination tables to compare and keep track of trending.</p>
<p>While the first challenge is building the flexibility that allows to query a table/view record count on any server, the second challenge is how to avoid resources hungry COUNT(*) that could lead to performance issues.</p>
<p>The following stored procedure does just that – capturing a record count virtually anywhere using sp_executesql with dynamic SQL and taking advantage of statistical record count from sys.dm_db_partition_stats to avoid performance problems.</p>
<p>&nbsp;</p>
<div id="wpshdo_5" class="wp-synhighlighter-outer"><div id="wpshdt_5" class="wp-synhighlighter-expanded"><table border="0" width="100%"><tr><td align="left" width="80%"><a name="#codesyntax_5"></a><a id="wpshat_5" class="wp-synhighlighter-title" href="#codesyntax_5"  onClick="javascript:wpsh_toggleBlock(5)" title="Click to show/hide code block">Source code</a></td><td align="right"><a href="#codesyntax_5" onClick="javascript:wpsh_code(5)" title="Show code only"><img decoding="async" border="0" style="border: 0 none" src="https://sqlsolutionsgroup.com/wp-content/plugins/wp-synhighlight/themes/default/images/code.png" /></a>&nbsp;<a href="#codesyntax_5" onClick="javascript:wpsh_print(5)" title="Print code"><img decoding="async" border="0" style="border: 0 none" src="https://sqlsolutionsgroup.com/wp-content/plugins/wp-synhighlight/themes/default/images/printer.png" /></a>&nbsp;<a href="https://sqlsolutionsgroup.com/wp-content/plugins/wp-synhighlight/About.html" target="_blank" title="Show plugin information"><img decoding="async" border="0" style="border: 0 none" src="https://sqlsolutionsgroup.com/wp-content/plugins/wp-synhighlight/themes/default/images/info.gif" /></a>&nbsp;</td></tr></table></div><div id="wpshdi_5" class="wp-synhighlighter-inner" style="display: block;"><pre class="tsql" style="font-family:monospace;"><span class="kw1">USE</span> <span class="br0">[</span>yourdatabasename<span class="br0">]</span>
 GO
 <span class="coMULTI">/****** Object:  StoredProcedure [dbo].[usp_GET_RecordCountfromAnyTable]    Script Date: 4/23/2019 3:41:40 PM ******/</span>
 <span class="kw1">SET</span> ANSI_<span class="sy0">NULL</span>S <span class="kw1">ON</span>
 GO
 <span class="kw1">SET</span> QUOTED_IDENTIFIER <span class="kw1">ON</span>
 GO
 <span class="co1">-- =============================================</span>
 <span class="co1">-- Author: Steve Rezhener</span>
 <span class="co1">-- Create date: 04/23/2019</span>
 <span class="co1">-- Description: Getting record count from any table anywhere (local/remote server)</span>
 <span class="co1">-- EXEC dbo.usp_GET_RecordCountfromAnyTable @TagName = 'AWS EC2', @ServerName= NULL, @DatabaseName='yourdatabase', @SchemaAndTableName='yourtablename'</span>
&nbsp;
<span class="kw1">CREATE</span> <span class="kw1">PROCEDURE</span> <span class="br0">[</span>dbo<span class="br0">]</span>.<span class="br0">[</span>usp_GET_RecordCountfromAnyTable<span class="br0">]</span>
@TagName <span class="kw1">AS</span> <span class="kw1">VARCHAR</span><span class="br0">&#40;</span>20<span class="br0">&#41;</span>
,@ServerName <span class="kw1">AS</span> <span class="kw1">VARCHAR</span><span class="br0">&#40;</span>100<span class="br0">&#41;</span>
,@DatabaseName <span class="kw1">AS</span> <span class="kw1">VARCHAR</span><span class="br0">&#40;</span>50<span class="br0">&#41;</span>
,@SchemaAndTableName <span class="kw1">AS</span> <span class="kw1">VARCHAR</span><span class="br0">&#40;</span>100<span class="br0">&#41;</span>
&nbsp;
<span class="kw1">AS</span>
<span class="kw1">BEGIN</span>
<span class="co1">-- SET NOCOUNT ON added to prevent extra result sets from</span>
<span class="co1">-- interfering with SELECT statements.</span>
<span class="kw1">SET</span> <span class="kw1">NOCOUNT</span> <span class="kw1">ON</span>;
&nbsp;
<span class="kw1">DECLARE</span> @SQLString1 <span class="kw1">AS</span> <span class="kw1">NVARCHAR</span><span class="br0">&#40;</span><span class="kw2">MAX</span><span class="br0">&#41;</span>
<span class="kw1">DECLARE</span> @SQLString2 <span class="kw1">AS</span> <span class="kw1">NVARCHAR</span><span class="br0">&#40;</span><span class="kw2">MAX</span><span class="br0">&#41;</span>
<span class="kw1">DECLARE</span> @ObjectID <span class="kw1">AS</span> <span class="kw1">BIGINT</span>
<span class="kw1">DECLARE</span> @ParmDefinition <span class="kw1">NVARCHAR</span><span class="br0">&#40;</span>500<span class="br0">&#41;</span>;
<span class="kw1">DECLARE</span> @SchemaName <span class="kw1">AS</span> <span class="kw1">VARCHAR</span><span class="br0">&#40;</span>50<span class="br0">&#41;</span> <span class="sy0">=</span> <span class="kw2">PARSENAME</span><span class="br0">&#40;</span>@SchemaAndTableName,2<span class="br0">&#41;</span>
<span class="kw1">DECLARE</span> @TableName <span class="kw1">AS</span> <span class="kw1">VARCHAR</span><span class="br0">&#40;</span>50<span class="br0">&#41;</span> <span class="sy0">=</span> <span class="kw2">PARSENAME</span><span class="br0">&#40;</span>@SchemaAndTableName,1<span class="br0">&#41;</span>
&nbsp;
&nbsp;
	<span class="kw1">IF</span> IS<span class="sy0">NULL</span><span class="br0">&#40;</span>@ServerName,<span class="kw2">@@SERVERNAME</span><span class="br0">&#41;</span> <span class="sy0">=</span> <span class="kw2">@@SERVERNAME</span> <span class="co1">-- local</span>
	<span class="kw1">BEGIN</span>
&nbsp;
		<span class="kw1">IF</span> @ServerName <span class="kw1">IS</span> <span class="sy0">NULL</span> <span class="kw1">SET</span> @ServerName <span class="sy0">=</span> <span class="kw2">@@SERVERNAME</span>
&nbsp;
		<span class="kw1">SET</span> @SQLString1 <span class="sy0">=</span> <span class="st0">'SELECT @ObjectIDOUT = tabs.OBJECT_ID
		FROM '</span> <span class="sy0">+</span> @DatabaseName <span class="sy0">+</span> <span class="st0">'.sys.tables AS tabs
		INNER JOIN '</span> <span class="sy0">+</span> @DatabaseName <span class="sy0">+</span> <span class="st0">'.sys.schemas AS mas ON tabs.schema_id = mas.schema_id
		WHERE 1=1
		AND tabs.name = '</span><span class="st0">''</span> <span class="sy0">+</span> @TableName <span class="sy0">+</span> <span class="st0">''</span><span class="st0">'
		AND mas.name = '</span><span class="st0">''</span> <span class="sy0">+</span> @SchemaName <span class="sy0">+</span> <span class="st0">''</span><span class="st0">'
		'</span>
&nbsp;
		<span class="kw1">PRINT</span> <span class="st0">'@SQLString1: '</span> <span class="sy0">+</span> @SQLString1
		<span class="kw1">SET</span> @ParmDefinition <span class="sy0">=</span> N<span class="st0">'@ObjectIDOUT BIGINT OUTPUT'</span>;
		<span class="kw1">EXECUTE</span> <span class="kw3">SP_EXECUTESQL</span> @SQLString1, @ParmDefinition, @ObjectIDOUT <span class="sy0">=</span> @ObjectID <span class="kw1">OUTPUT</span>
		<span class="kw1">PRINT</span> <span class="st0">'@ObjectID: '</span> <span class="sy0">+</span> <span class="kw1">CONVERT</span><span class="br0">&#40;</span><span class="kw1">VARCHAR</span>,@ObjectID<span class="br0">&#41;</span>
&nbsp;
		<span class="kw1">SET</span> @SQLString2 <span class="sy0">=</span> N<span class="st0">'SELECT '</span><span class="st0">''</span> <span class="sy0">+</span> @TagName <span class="sy0">+</span> <span class="st0">''</span><span class="st0">' AS TagName, '</span><span class="st0">''</span> <span class="sy0">+</span> @ServerName <span class="sy0">+</span> <span class="st0">''</span><span class="st0">' AS ServerName, '</span><span class="st0">''</span> <span class="sy0">+</span> @DatabaseName <span class="sy0">+</span> <span class="st0">''</span><span class="st0">' AS DatabaseName, '</span><span class="st0">''</span> <span class="sy0">+</span> @SchemaAndTableName <span class="sy0">+</span> <span class="st0">''</span><span class="st0">' AS SchemaAndTableName, row_count AS RecCount
		FROM '</span> <span class="sy0">+</span> @DatabaseName <span class="sy0">+</span> <span class="st0">'.sys.dm_db_partition_stats
		WHERE 1=1 AND object_id = '</span> <span class="sy0">+</span> <span class="kw1">CONVERT</span><span class="br0">&#40;</span><span class="kw1">VARCHAR</span>,@ObjectID<span class="br0">&#41;</span> <span class="sy0">+</span> <span class="st0">' AND index_id=1'</span>
&nbsp;
&nbsp;
		<span class="kw1">PRINT</span> <span class="st0">'@SQLString2: '</span> <span class="sy0">+</span> @SQLString2
		<span class="kw1">EXECUTE</span> <span class="kw3">SP_EXECUTESQL</span> @SQLString2
&nbsp;
	<span class="kw1">END</span>
	<span class="kw1">ELSE</span> <span class="co1">-- remote server via linked server</span>
	<span class="kw1">BEGIN</span>
&nbsp;
		<span class="kw1">SET</span> @SQLString1 <span class="sy0">=</span> <span class="st0">'SELECT @ObjectIDOUT = tabs.OBJECT_ID
		FROM ['</span> <span class="sy0">+</span> @ServerName <span class="sy0">+</span> <span class="st0">'].'</span> <span class="sy0">+</span> @DatabaseName <span class="sy0">+</span> <span class="st0">'.sys.tables AS tabs
		INNER JOIN ['</span> <span class="sy0">+</span> @ServerName <span class="sy0">+</span> <span class="st0">'].'</span> <span class="sy0">+</span> @DatabaseName <span class="sy0">+</span> <span class="st0">'.sys.schemas AS mas ON tabs.schema_id = mas.schema_id
		WHERE 1=1
		AND tabs.name = '</span><span class="st0">''</span> <span class="sy0">+</span> @TableName <span class="sy0">+</span> <span class="st0">''</span><span class="st0">'
		AND mas.name = '</span><span class="st0">''</span> <span class="sy0">+</span> @SchemaName <span class="sy0">+</span> <span class="st0">''</span><span class="st0">'
		'</span>
&nbsp;
		<span class="kw1">PRINT</span> <span class="st0">'@SQLString1: '</span> <span class="sy0">+</span> @SQLString1
		<span class="kw1">SET</span> @ParmDefinition <span class="sy0">=</span> N<span class="st0">'@ObjectIDOUT BIGINT OUTPUT'</span>;
		<span class="kw1">EXECUTE</span> <span class="kw3">SP_EXECUTESQL</span> @SQLString1, @ParmDefinition, @ObjectIDOUT <span class="sy0">=</span> @ObjectID <span class="kw1">OUTPUT</span>
		<span class="kw1">PRINT</span> <span class="st0">'@ObjectID'</span> <span class="sy0">+</span> <span class="kw1">CONVERT</span><span class="br0">&#40;</span><span class="kw1">VARCHAR</span>,@ObjectID<span class="br0">&#41;</span>
&nbsp;
&nbsp;
		<span class="kw1">SET</span> @SQLString2 <span class="sy0">=</span> N<span class="st0">'SELECT '</span><span class="st0">''</span> <span class="sy0">+</span> @TagName <span class="sy0">+</span> <span class="st0">''</span><span class="st0">' AS TagName, '</span><span class="st0">''</span> <span class="sy0">+</span> @ServerName <span class="sy0">+</span> <span class="st0">''</span><span class="st0">' AS ServerName, '</span><span class="st0">''</span> <span class="sy0">+</span> @DatabaseName <span class="sy0">+</span> <span class="st0">''</span><span class="st0">' AS DatabaseName, '</span><span class="st0">''</span> <span class="sy0">+</span> @SchemaAndTableName <span class="sy0">+</span> <span class="st0">''</span><span class="st0">' AS SchemaAndTableName, row_count AS RecCount
		FROM ['</span> <span class="sy0">+</span> @ServerName <span class="sy0">+</span> <span class="st0">'].'</span> <span class="sy0">+</span> @DatabaseName <span class="sy0">+</span> <span class="st0">'.sys.dm_db_partition_stats
		WHERE 1=1 AND object_id = '</span> <span class="sy0">+</span> <span class="kw1">CONVERT</span><span class="br0">&#40;</span><span class="kw1">VARCHAR</span>,@ObjectID<span class="br0">&#41;</span> <span class="sy0">+</span> <span class="st0">' AND index_id=1'</span>
		<span class="co1">--PRINT '@SQLString2: ' + @SQLString2</span>
&nbsp;
&nbsp;
		<span class="kw1">PRINT</span> <span class="st0">'@SQLString2: '</span> <span class="sy0">+</span> @SQLString2
		<span class="kw1">EXECUTE</span> <span class="kw3">SP_EXECUTESQL</span> @SQLString2
&nbsp;
	<span class="kw1">END</span>
&nbsp;
<span class="kw1">END</span></pre></div></div>
<p>Equipped with this stored procedure, it is just a matter of time that you can build an operational report to look sharp and shinny that you can share with your business users, as you can see in this image: </p>
<p><a href="https://sqlsolutionsgroup.com/wp-content/uploads/2020/03/stored_proc1.jpg"><img loading="lazy" decoding="async" class="aligncenter wp-image-4596 size-full" src="https://sqlsolutionsgroup.com/wp-content/uploads/2020/03/stored_proc1.jpg" alt="get a record count" width="816" height="389" srcset="https://sqlsolutionsgroup.com/wp-content/uploads/2020/03/stored_proc1.jpg 816w, https://sqlsolutionsgroup.com/wp-content/uploads/2020/03/stored_proc1-300x143.jpg 300w, https://sqlsolutionsgroup.com/wp-content/uploads/2020/03/stored_proc1-768x366.jpg 768w" sizes="(max-width: 816px) 100vw, 816px" /></a></p>
<p>The post <a href="https://sqlsolutionsgroup.com/get-a-record-count/">Data Governance – your ultimate stored procedure to get a record count from any table and compare</a> appeared first on <a href="https://sqlsolutionsgroup.com">SQL Solutions Group</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Bringing back an informative SQL Server Agent job email notification on failed SSIS packages</title>
		<link>https://sqlsolutionsgroup.com/agent-job-email-notification/</link>
		
		<dc:creator><![CDATA[Steve Rezhener]]></dc:creator>
		<pubDate>Mon, 17 Feb 2020 16:58:06 +0000</pubDate>
				<category><![CDATA[SQL Group]]></category>
		<category><![CDATA[SQL Server]]></category>
		<category><![CDATA[#microsftcertifedmaster]]></category>
		<category><![CDATA[#microsftpartner]]></category>
		<category><![CDATA[#SQLAB]]></category>
		<category><![CDATA[#SQlatino]]></category>
		<category><![CDATA[#SQlatinoamerica]]></category>
		<category><![CDATA[#sqldatabase]]></category>
		<category><![CDATA[#sqldeveloper]]></category>
		<category><![CDATA[#SQLgroupie]]></category>
		<category><![CDATA[#sqlimer]]></category>
		<category><![CDATA[#sqlimerbymay]]></category>
		<category><![CDATA[#sqlinjection]]></category>
		<category><![CDATA[#sqlinternals]]></category>
		<category><![CDATA[#sqlite]]></category>
		<category><![CDATA[#sqlite3]]></category>
		<category><![CDATA[#SQLLearning]]></category>
		<category><![CDATA[#SQLMagazine]]></category>
		<category><![CDATA[#sqlmanagementstudio]]></category>
		<category><![CDATA[#sqlmanager]]></category>
		<category><![CDATA[#Sqlmap]]></category>
		<category><![CDATA[#sqlrun]]></category>
		<category><![CDATA[#sqlsaturday2017]]></category>
		<category><![CDATA[#sqlsatvienna]]></category>
		<category><![CDATA[#sqlserver]]></category>
		<category><![CDATA[#SQLserver2012]]></category>
		<category><![CDATA[#sqlserver2014]]></category>
		<category><![CDATA[#sqlserver2017]]></category>
		<category><![CDATA[#sqlserver2022]]></category>
		<category><![CDATA[#SQLServeronLinux]]></category>
		<category><![CDATA[#SQLsolutionsgroup]]></category>
		<category><![CDATA[#SQLTraining]]></category>
		<category><![CDATA[#SQLYog]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[SQLPASS]]></category>
		<category><![CDATA[SQLSaturday]]></category>
		<category><![CDATA[SSG]]></category>
		<category><![CDATA[SSIS]]></category>
		<guid isPermaLink="false">https://sqlsolutionsgroup.com/?p=4576</guid>

					<description><![CDATA[<p>The post <a href="https://sqlsolutionsgroup.com/agent-job-email-notification/">Bringing back an informative SQL Server Agent job email notification on failed SSIS packages</a> appeared first on <a href="https://sqlsolutionsgroup.com">SQL Solutions Group</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<h3><strong>Introduction</strong></h3>
<p>The SSISDB database (a.k.a. the Integration Services catalog) was introduced back in SQL Server 2012 as a way to de-clutter MSDB database and provide some built-in logging and reporting infrastructure. In a nutshell, SSISDB is an SSIS framework (see Fig #1) making SQL Server Integration Services more robust and enterprise-friendly by providing the following features:</p>
<ul>
<li>Database backup</li>
<li>Database encryption</li>
<li>Support for environments</li>
<li>Support project and package parameters</li>
<li>Package versioning</li>
<li>Custom SSRS performance reports built into SSMS</li>
<li>Support for deployment within SSDT</li>
</ul>
<p><a href="https://sqlsolutionsgroup.com/wp-content/uploads/2020/02/jobfailed2.jpg"><img loading="lazy" decoding="async" class="aligncenter size-full wp-image-4577" src="https://sqlsolutionsgroup.com/wp-content/uploads/2020/02/jobfailed2.jpg" alt="" width="294" height="559" srcset="https://sqlsolutionsgroup.com/wp-content/uploads/2020/02/jobfailed2.jpg 294w, https://sqlsolutionsgroup.com/wp-content/uploads/2020/02/jobfailed2-158x300.jpg 158w" sizes="(max-width: 294px) 100vw, 294px" /></a></p>
<p>While overall SSISDB Catalog was and still is a great enhancement to SQL Server Integration Services, some previously working fine feature took a wrong turn. This blog post is going to cover the “behavioral” changes that Microsoft made to SQL Server Agent job notification as part of the SSISDB Catalog, specifically the error message reporting on failed package.</p>
<h3><strong>Problem</strong></h3>
<p>Prior to SQL Server 2012, an email notification on a failed SQL Server Agent job step with an SSIS package was really informative. The error message was specific enough, as it was providing the error from the SSIS execution engine. When Microsoft introduced SQL Server 2012, it decided to replace this specific SQL Server Agent job email notification with a generic message directing the user to the SSIS Catalog error log (see Fig #2).</p>
<p><a href="https://sqlsolutionsgroup.com/wp-content/uploads/2020/02/jobfailed1.jpg"><img loading="lazy" decoding="async" class="aligncenter wp-image-4578 " src="https://sqlsolutionsgroup.com/wp-content/uploads/2020/02/jobfailed1.jpg" alt="SQL Server Agent job email notification" width="574" height="182" srcset="https://sqlsolutionsgroup.com/wp-content/uploads/2020/02/jobfailed1.jpg 993w, https://sqlsolutionsgroup.com/wp-content/uploads/2020/02/jobfailed1-300x95.jpg 300w, https://sqlsolutionsgroup.com/wp-content/uploads/2020/02/jobfailed1-768x244.jpg 768w" sizes="(max-width: 574px) 100vw, 574px" /></a></p>
<p>I’m assuming when most of us are receiving Operational emails, we want to know not only if to react or not, but also how to react. This is especially important now, since we use mobile devices to read emails and might not have access to the a real computer.</p>
<p>Unfortunately, the email above gives only an indication that some SSIS package failed without giving any details. For example, in the past (prior to SQL Server 2012), you would know that your package failed due to connectivity issue by just reading an email and decide to ignore the notification. Now you don’t have that option. You would need a real computer to fire-up SSMS and run a custom SSRS on that package, adding many clicks to see the details error. Needless to say, running to your desktop/laptop to open SSMS only to discover connectivity problems is unnecessary overkill.</p>
<h3><strong>Solution: Use T-SQL to create a better SQL Server Agent job email notification </strong></h3>
<p>The solution will involve a T-SQL query (I should probably make it a stored procedure at some point) that would connect tables and records between both MSDB and SSISDB databases to bring back a detailed message on a failed SSIS package. Equipped with an email that has detailed error message, you can react without leaving your couch – fix it or just let it retry.</p>
<p>In a nutshell this solution is to going to:</p>
<ol>
<li>Find the job name based on a current SPID</li>
<li>Find a job with a failed step</li>
<li>Connect step with SSIS package name</li>
<li>Use the SSIS package name to find run-time errors in SSISDB catalog</li>
<li>Bubble us to an inner exception to include only detailed error</li>
<li>Locate a default job operator</li>
<li>Send a detailed error report</li>
</ol>
<p>The following script would need to be added as last step in a job (you can disable the job alert) with all the steps that include SSIS packages going to that last step on failure (Fig 3).</p>
<p><a href="https://sqlsolutionsgroup.com/wp-content/uploads/2020/02/jobfailed3.png"><img loading="lazy" decoding="async" class="aligncenter  wp-image-4579" src="https://sqlsolutionsgroup.com/wp-content/uploads/2020/02/jobfailed3.png" alt="" width="575" height="382" srcset="https://sqlsolutionsgroup.com/wp-content/uploads/2020/02/jobfailed3.png 691w, https://sqlsolutionsgroup.com/wp-content/uploads/2020/02/jobfailed3-300x199.png 300w" sizes="(max-width: 575px) 100vw, 575px" /></a></p>
<p>Additionally, the used-to-be last step before Report SSIS failure was introduced that will now precede that step will need to quit the job reporting success (Fig 4) instead of continuing to the next step.<a href="https://sqlsolutionsgroup.com/wp-content/uploads/2020/02/jobfailed4.png"><img loading="lazy" decoding="async" class="aligncenter  wp-image-4580" src="https://sqlsolutionsgroup.com/wp-content/uploads/2020/02/jobfailed4.png" alt="" width="576" height="275" srcset="https://sqlsolutionsgroup.com/wp-content/uploads/2020/02/jobfailed4.png 893w, https://sqlsolutionsgroup.com/wp-content/uploads/2020/02/jobfailed4-300x143.png 300w, https://sqlsolutionsgroup.com/wp-content/uploads/2020/02/jobfailed4-768x367.png 768w" sizes="(max-width: 576px) 100vw, 576px" />.</a></p>
<div id="wpshdo_6" class="wp-synhighlighter-outer"><div id="wpshdt_6" class="wp-synhighlighter-expanded"><table border="0" width="100%"><tr><td align="left" width="80%"><a name="#codesyntax_6"></a><a id="wpshat_6" class="wp-synhighlighter-title" href="#codesyntax_6"  onClick="javascript:wpsh_toggleBlock(6)" title="Click to show/hide code block">Source code</a></td><td align="right"><a href="#codesyntax_6" onClick="javascript:wpsh_code(6)" title="Show code only"><img decoding="async" border="0" style="border: 0 none" src="https://sqlsolutionsgroup.com/wp-content/plugins/wp-synhighlight/themes/default/images/code.png" /></a>&nbsp;<a href="#codesyntax_6" onClick="javascript:wpsh_print(6)" title="Print code"><img decoding="async" border="0" style="border: 0 none" src="https://sqlsolutionsgroup.com/wp-content/plugins/wp-synhighlight/themes/default/images/printer.png" /></a>&nbsp;<a href="https://sqlsolutionsgroup.com/wp-content/plugins/wp-synhighlight/About.html" target="_blank" title="Show plugin information"><img decoding="async" border="0" style="border: 0 none" src="https://sqlsolutionsgroup.com/wp-content/plugins/wp-synhighlight/themes/default/images/info.gif" /></a>&nbsp;</td></tr></table></div><div id="wpshdi_6" class="wp-synhighlighter-inner" style="display: block;"><pre class="tsql" style="font-family:monospace;"><span class="kw1">DECLARE</span> @Full_ssis_command <span class="kw1">VARCHAR</span><span class="br0">&#40;</span>4000<span class="br0">&#41;</span>,
 @Job_step_id <span class="kw1">INT</span>,
 @Package_name <span class="kw1">VARCHAR</span><span class="br0">&#40;</span>4000<span class="br0">&#41;</span>,
 @EMailBody <span class="kw1">NVARCHAR</span><span class="br0">&#40;</span>2000<span class="br0">&#41;</span>,
 @EMailSubject <span class="kw1">VARCHAR</span><span class="br0">&#40;</span><span class="nu0">150</span><span class="br0">&#41;</span>,
 <span class="co1">--@Job_name VARCHAR(100),</span>
 @Job_id <span class="kw1">UNIQUEIDENTIFIER</span>
&nbsp;
<span class="kw1">SELECT</span>	@Job_id <span class="sy0">=</span> Job_id
		<span class="co1">--@Job_name = [name] --AS job_name</span>
<span class="kw1">FROM</span>	sys.<span class="me1">dm_exec_sessions</span> <span class="kw1">AS</span> ions
	<span class="kw1">INNER</span> join msdb.<span class="me1">dbo</span>.<span class="me1">sysjobs</span> <span class="kw1">AS</span> jobs <span class="kw1">ON</span> jobs.<span class="me1">job_id</span>
				<span class="sy0">=</span> <span class="kw1">CAST</span><span class="br0">&#40;</span><span class="kw1">CONVERT</span><span class="br0">&#40;</span><span class="kw1">BINARY</span><span class="br0">&#40;</span>16<span class="br0">&#41;</span>, <span class="kw2">SUBSTRING</span><span class="br0">&#40;</span>ions.<span class="br0">[</span>program_name<span class="br0">]</span>,<span class="kw2">CHARINDEX</span><span class="br0">&#40;</span><span class="st0">'(Job 0x'</span>,ions.<span class="br0">[</span>program_name<span class="br0">]</span>,1<span class="br0">&#41;</span> <span class="sy0">+</span> 5 , 34<span class="br0">&#41;</span>,1<span class="br0">&#41;</span> <span class="kw1">AS</span> <span class="kw1">UNIQUEIDENTIFIER</span><span class="br0">&#41;</span>
<span class="kw1">WHERE</span>	1<span class="sy0">=</span>1
	<span class="sy0">AND</span> ions.<span class="me1">session_id</span> <span class="sy0">=</span> <span class="kw2">@@SPID</span> <span class="co1">--63</span>
&nbsp;
<span class="co1">--print @Job_name</span>
&nbsp;
<span class="kw1">SELECT</span> <span class="kw1">TOP</span> 1 @Job_step_id <span class="sy0">=</span> Step_id
<span class="kw1">FROM</span> msdb.<span class="me1">dbo</span>.<span class="me1">sysjobhistory</span> <span class="br0">&#40;</span>NOLOCK<span class="br0">&#41;</span>
<span class="kw1">WHERE</span> Run_status <span class="sy0">&lt;&gt;</span> 1
 <span class="sy0">AND</span> Step_id <span class="sy0">&gt;</span> 0
 <span class="sy0">AND</span> Job_id <span class="sy0">=</span> @Job_id
<span class="kw1">ORDER</span> <span class="kw1">BY</span> Instance_id <span class="kw1">DESC</span>
&nbsp;
<span class="kw1">SELECT</span> @Full_ssis_command <span class="sy0">=</span> Command
<span class="kw1">FROM</span> msdb.<span class="me1">dbo</span>.<span class="me1">sysjobsteps</span> <span class="br0">&#40;</span>NOLOCK<span class="br0">&#41;</span>
<span class="kw1">WHERE</span> Job_id <span class="sy0">=</span> @Job_id
 <span class="sy0">AND</span> Step_id <span class="sy0">=</span> @Job_step_id
&nbsp;
 <span class="kw1">PRINT</span> @Full_ssis_command
&nbsp;
<span class="kw1">IF</span> @Full_ssis_command <span class="sy0">LIKE</span> <span class="st0">'%.dtsx%'</span>
 <span class="kw1">BEGIN</span>
 <span class="kw1">SELECT</span> @Package_name <span class="sy0">=</span> <span class="kw1">RIGHT</span><span class="br0">&#40;</span><span class="kw1">LEFT</span><span class="br0">&#40;</span>@Full_ssis_command,<span class="kw2">CHARINDEX</span><span class="br0">&#40;</span><span class="st0">'.dtsx'</span>, @Full_ssis_command<span class="br0">&#41;</span><span class="br0">&#41;</span>, <span class="kw2">CHARINDEX</span><span class="br0">&#40;</span><span class="st0">'<span class="es0">\'</span>, Reverse(LEFT(@Full_ssis_command, Charindex('</span>.<span class="me1">dtsx</span><span class="st0">', @Full_ssis_command)-1)))) + '</span>dtsx<span class="st0">'
 END
&nbsp;
SELECT TOP 1 @EMailBody = LEFT([Message], 2000), @EMailSubject = '</span>Package : <span class="st0">' + Package_name + '</span> failed <span class="kw1">ON</span> :<span class="st0">' + CONVERT(VARCHAR,Message_time)
--[Message_time],
-- [Extended_info_id],
-- [Package_name],
-- [Message_source_name],
-- [Subcomponent_name],
-- [Package_path],
-- [Execution_path],
-- LEFT([Message], 400)
FROM SSISDB.[catalog].[Event_messages] (NOLOCK)
WHERE [Package_name] = @Package_name
 AND Event_name = '</span>OnError<span class="st0">'
 AND Message_time &gt;= DATEADD(DD,0,DATEDIFF(DD,0,GETDATE()))
 AND Operation_id IN (SELECT Max(Operation_id)
 FROM SSISDB.[catalog].[Event_messages](NOLOCK)
 WHERE [Package_name] = @Package_name)
ORDER BY Message_time ASC
&nbsp;
DECLARE @operator_name AS VARCHAR(100) = (SELECT top 1 name from msdb.dbo.sysoperators)
PRINT @operator_name
&nbsp;
exec msdb.dbo.sp_notify_operator  @profile_name = NULL ,
    @id = NULL,
    @name = @operator_name,  
    @subject = @EMailSubject,  
    @body = @EMailBody</span></pre></div></div>
<p>Here is the improved SQL Server Agent job email notification with a detailed message that we can expect now (Fig 5).</p>
<figure class="wp-block-gallery columns-1 is-cropped">
<p><a href="https://sqlsolutionsgroup.com/wp-content/uploads/2020/02/jobfailed5.jpg"><img loading="lazy" decoding="async" class="aligncenter wp-image-4581 " src="https://sqlsolutionsgroup.com/wp-content/uploads/2020/02/jobfailed5.jpg" alt="SQL Server Agent job email notification" width="575" height="118" srcset="https://sqlsolutionsgroup.com/wp-content/uploads/2020/02/jobfailed5.jpg 939w, https://sqlsolutionsgroup.com/wp-content/uploads/2020/02/jobfailed5-300x62.jpg 300w, https://sqlsolutionsgroup.com/wp-content/uploads/2020/02/jobfailed5-768x158.jpg 768w" sizes="(max-width: 575px) 100vw, 575px" /></a></p>
<h3><strong>Assumptions:</strong></h3>
<ol>
<li>DatabaseMail is enabled and functioning</li>
<li>DatabaseMail has a public and default mail profile</li>
<li>There is at least one configured Operator</li>
</ol>
<p><strong>Disclaimer</strong></p>
<p>This blog post is partially based on the following blog posts/forum discussions:</p>
<p><a href="https://www.sqlservercentral.com/forums/topic/identifying-sql-agent-job-name-based-on-the-job-id">https://www.sqlservercentral.com/forums/topic/identifying-sql-agent-job-name-based-on-the-job-id</a></p>
<p><a href="https://thebakingdba.blogspot.com/2012/11/sql-server-2012-ssis-getting-useful.html">https://thebakingdba.blogspot.com/2012/11/sql-server-2012-ssis-getting-useful.html</a></p>
</figure>


<p>The post <a href="https://sqlsolutionsgroup.com/agent-job-email-notification/">Bringing back an informative SQL Server Agent job email notification on failed SSIS packages</a> appeared first on <a href="https://sqlsolutionsgroup.com">SQL Solutions Group</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>How to fix a failed &#8220;SSIS Server Maintenance Job&#8221; job</title>
		<link>https://sqlsolutionsgroup.com/failed-ssis-job/</link>
					<comments>https://sqlsolutionsgroup.com/failed-ssis-job/#comments</comments>
		
		<dc:creator><![CDATA[Steve Rezhener]]></dc:creator>
		<pubDate>Tue, 28 Jan 2020 04:09:00 +0000</pubDate>
				<category><![CDATA[SQL Group]]></category>
		<category><![CDATA[SQL Server]]></category>
		<category><![CDATA[#microsftcertifedmaster]]></category>
		<category><![CDATA[#microsftpartner]]></category>
		<category><![CDATA[#SQLAB]]></category>
		<category><![CDATA[#SQlatino]]></category>
		<category><![CDATA[#SQlatinoamerica]]></category>
		<category><![CDATA[#sqldatabase]]></category>
		<category><![CDATA[#sqldeveloper]]></category>
		<category><![CDATA[#SQLgroupie]]></category>
		<category><![CDATA[#sqlimer]]></category>
		<category><![CDATA[#sqlimerbymay]]></category>
		<category><![CDATA[#sqlinjection]]></category>
		<category><![CDATA[#sqlinternals]]></category>
		<category><![CDATA[#sqlite]]></category>
		<category><![CDATA[#sqlite3]]></category>
		<category><![CDATA[#SQLLearning]]></category>
		<category><![CDATA[#SQLMagazine]]></category>
		<category><![CDATA[#sqlmanagementstudio]]></category>
		<category><![CDATA[#sqlmanager]]></category>
		<category><![CDATA[#Sqlmap]]></category>
		<category><![CDATA[#sqlrun]]></category>
		<category><![CDATA[#sqlsaturday2017]]></category>
		<category><![CDATA[#sqlsatvienna]]></category>
		<category><![CDATA[#sqlserver]]></category>
		<category><![CDATA[#SQLserver2012]]></category>
		<category><![CDATA[#sqlserver2014]]></category>
		<category><![CDATA[#sqlserver2017]]></category>
		<category><![CDATA[#sqlserver2022]]></category>
		<category><![CDATA[#SQLServeronLinux]]></category>
		<category><![CDATA[#SQLsolutionsgroup]]></category>
		<category><![CDATA[#SQLTraining]]></category>
		<category><![CDATA[#SQLYog]]></category>
		<category><![CDATA[maintenance]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[SQLPASS]]></category>
		<category><![CDATA[SQLSaturday]]></category>
		<category><![CDATA[SSG]]></category>
		<category><![CDATA[SSIS]]></category>
		<guid isPermaLink="false">https://sqlsolutionsgroup.com/?p=4529</guid>

					<description><![CDATA[<p>The post <a href="https://sqlsolutionsgroup.com/failed-ssis-job/">How to fix a failed &#8220;SSIS Server Maintenance Job&#8221; job</a> appeared first on <a href="https://sqlsolutionsgroup.com">SQL Solutions Group</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>In this article we will explore how to fix a failed “SSIS Server Maintenance Job”.</p>
<p><strong>Introduction</strong></p>
<p>The SSISDB database (a.k.a. the Integration Services catalog) was introduced back in SQL Server 2012 as a way to de-clutter the MSDB database and provide some built-in logging and reporting infrastructure. In a nutshell, SSISDB is an SSIS framework making SQL Server Integration Services more robust and enterprise-friendly by providing the following features:</p>
<ul>
<li>Database backup</li>
<li>Database encryption</li>
<li>Support for environments</li>
<li>Support project and package parameters</li>
<li>Package versioning</li>
<li>Custom SSRS performance reports built into SSMS</li>
<li>Deployment directly from SSDT</li>
</ul>
<p>Since SSISDB Catalog is going to log package run-time information, Microsoft created a SQL Server Agent job (SSIS Server Maintenance Job, see Fig .1) to do the in-house cleaning. This job is running two steps (see Fig 2) to enforce the data retention policy (based on SSISDB Catalog settings) instead of letting all the data collection activities to eat all your disk space and effectively brake your SSIS run-time service (if logging is enabled). </p>
<figure id="attachment_4530" aria-describedby="caption-attachment-4530" style="width: 816px" class="wp-caption aligncenter"><a href="https://sqlsolutionsgroup.com/wp-content/uploads/2020/01/failedSSIS1.png"><img loading="lazy" decoding="async" class="wp-image-4530 size-full" src="https://sqlsolutionsgroup.com/wp-content/uploads/2020/01/failedSSIS1.png" alt="failed SSIS" width="816" height="501" srcset="https://sqlsolutionsgroup.com/wp-content/uploads/2020/01/failedSSIS1.png 816w, https://sqlsolutionsgroup.com/wp-content/uploads/2020/01/failedSSIS1-300x184.png 300w, https://sqlsolutionsgroup.com/wp-content/uploads/2020/01/failedSSIS1-768x472.png 768w" sizes="(max-width: 816px) 100vw, 816px" /></a><figcaption id="caption-attachment-4530" class="wp-caption-text">Figure 1: The Job</figcaption></figure>
<p>&nbsp;</p>
<figure id="attachment_4531" aria-describedby="caption-attachment-4531" style="width: 904px" class="wp-caption aligncenter"><a href="https://sqlsolutionsgroup.com/wp-content/uploads/2020/01/failedSSIS2.png"><img loading="lazy" decoding="async" class="wp-image-4531 size-full" src="https://sqlsolutionsgroup.com/wp-content/uploads/2020/01/failedSSIS2.png" alt="" width="904" height="182" srcset="https://sqlsolutionsgroup.com/wp-content/uploads/2020/01/failedSSIS2.png 904w, https://sqlsolutionsgroup.com/wp-content/uploads/2020/01/failedSSIS2-300x60.png 300w, https://sqlsolutionsgroup.com/wp-content/uploads/2020/01/failedSSIS2-768x155.png 768w" sizes="(max-width: 904px) 100vw, 904px" /></a><figcaption id="caption-attachment-4531" class="wp-caption-text">Figure 2: Job Steps</figcaption></figure>
<p>While SSIS Server Operation Records Maintenance (a.k.a. step #1) is in charge of removing all the old (default=365 days) logging, SSIS Server Max Version Per Project Maintenance (a.k.a. step #2) is in change of removing all old (default=10 versions) package versioning.</p>
<p><strong>Problem</strong></p>
<p>“SSIS Server Maintenance Job” SQL Server Agent job started to fail  with the following error:</p>
<blockquote>Executed as user: #MS_SSISServerCleanupJobLogin##. A cursor with the name ‘execution_cursor’ does not exist. [SQLSTATE 34000] (Error 16916)</blockquote>
<p>This run-time error (trying to deallocate a CURSOR that doesn’t exist) happens inside Step #1 which runs a ssisdb.internal.cleanup_server_retention_window stored procedure. I’m  going to speculate and say that this bug was unintentionally introduced by adding more features (most likely, it’s the server_operation_encryption_level which was introduced with SQL Server 2012 SP2). While I first spotted this problem in SQL Server 2017 with CU12, unfortunately it’s still a problem as of December 2019 with the latest and greatest CU18 (14.0.3257.3).</p>
<p><strong>Solution</strong></p>
<p>You can wait for Microsoft to fix it in a next CU (a.k.a. Cumulative Update) or you can fix it yourself by modifying the code inside ssisdb.internal.cleanup_server_retention_window stored procedure.</p>
<p>A little warning here: You are going to be modifying the code that was created by Microsoft. You need to be comfortable with taking that risk.</p>
<p>You would need to alter the procedure by moving a DEALLOCATE statement from line #175 to #177 to fix this failed SSIS job (see Fig #3).</p>
<figure id="attachment_4532" aria-describedby="caption-attachment-4532" style="width: 675px" class="wp-caption aligncenter"><a href="https://sqlsolutionsgroup.com/wp-content/uploads/2020/01/FailedSSIS3.jpg"><img loading="lazy" decoding="async" class="wp-image-4532 size-full" src="https://sqlsolutionsgroup.com/wp-content/uploads/2020/01/FailedSSIS3.jpg" alt="" width="675" height="322" srcset="https://sqlsolutionsgroup.com/wp-content/uploads/2020/01/FailedSSIS3.jpg 675w, https://sqlsolutionsgroup.com/wp-content/uploads/2020/01/FailedSSIS3-300x143.jpg 300w" sizes="(max-width: 675px) 100vw, 675px" /></a><figcaption id="caption-attachment-4532" class="wp-caption-text">Figure 3: Solution</figcaption></figure>
<p>This post is based on <span style="text-decoration: underline;"><a href="https://social.msdn.microsoft.com/Forums/sqlserver/en-US/238eb212-f757-4ce8-acea-e4c579628bd2/ssis-server-maintenance-cleanupserverretentionwindow-job-error?forum=sqlintegrationservices#dbf31af9-2bd2-4922-8b22-167453c827d9">this MSDN post</a></span>.</p>
<p>The post <a href="https://sqlsolutionsgroup.com/failed-ssis-job/">How to fix a failed &#8220;SSIS Server Maintenance Job&#8221; job</a> appeared first on <a href="https://sqlsolutionsgroup.com">SQL Solutions Group</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://sqlsolutionsgroup.com/failed-ssis-job/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>Can not create Catalog (SSISDB) due to an error</title>
		<link>https://sqlsolutionsgroup.com/catalog-ssisdb/</link>
					<comments>https://sqlsolutionsgroup.com/catalog-ssisdb/#comments</comments>
		
		<dc:creator><![CDATA[Steve Rezhener]]></dc:creator>
		<pubDate>Tue, 14 Jan 2020 07:09:00 +0000</pubDate>
				<category><![CDATA[SQL Group]]></category>
		<category><![CDATA[SQL Server]]></category>
		<category><![CDATA[#microsftcertifedmaster]]></category>
		<category><![CDATA[#microsftpartner]]></category>
		<category><![CDATA[#SQLAB]]></category>
		<category><![CDATA[#SQlatino]]></category>
		<category><![CDATA[#SQlatinoamerica]]></category>
		<category><![CDATA[#sqldatabase]]></category>
		<category><![CDATA[#sqldeveloper]]></category>
		<category><![CDATA[#SQLgroupie]]></category>
		<category><![CDATA[#sqlimer]]></category>
		<category><![CDATA[#sqlimerbymay]]></category>
		<category><![CDATA[#sqlinjection]]></category>
		<category><![CDATA[#sqlinternals]]></category>
		<category><![CDATA[#sqlite]]></category>
		<category><![CDATA[#sqlite3]]></category>
		<category><![CDATA[#SQLLearning]]></category>
		<category><![CDATA[#SQLMagazine]]></category>
		<category><![CDATA[#sqlmanagementstudio]]></category>
		<category><![CDATA[#sqlmanager]]></category>
		<category><![CDATA[#Sqlmap]]></category>
		<category><![CDATA[#sqlrun]]></category>
		<category><![CDATA[#sqlsaturday2017]]></category>
		<category><![CDATA[#sqlsatvienna]]></category>
		<category><![CDATA[#sqlserver]]></category>
		<category><![CDATA[#SQLserver2012]]></category>
		<category><![CDATA[#sqlserver2014]]></category>
		<category><![CDATA[#sqlserver2017]]></category>
		<category><![CDATA[#sqlserver2022]]></category>
		<category><![CDATA[#SQLServeronLinux]]></category>
		<category><![CDATA[#SQLsolutionsgroup]]></category>
		<category><![CDATA[#SQLTraining]]></category>
		<category><![CDATA[#SQLYog]]></category>
		<category><![CDATA[Catalog]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[SQLPASS]]></category>
		<category><![CDATA[SQLSaturday]]></category>
		<category><![CDATA[SSG]]></category>
		<category><![CDATA[SSIS]]></category>
		<guid isPermaLink="false">https://sqlsolutionsgroup.com/?p=4513</guid>

					<description><![CDATA[<p>The post <a href="https://sqlsolutionsgroup.com/catalog-ssisdb/">Can not create Catalog (SSISDB) due to an error</a> appeared first on <a href="https://sqlsolutionsgroup.com">SQL Solutions Group</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<h3><strong>Introduction</strong></h3>
<p>The SSISDB database (a.k.a. the SQL Server Integration Services catalog) was introduced back in SQL Server 2012 as a way to de-clutter the MSDB database and provide some built-in logging and reporting infrastructure. In a nutshell, SSISDB is an SSIS framework making SQL Server Integration Services more robust and enterprise-friendly by providing the following features:</p>
<ul>
<li>Database backup</li>
<li>Database encryption</li>
<li>Support for environments</li>
<li>Support project and package parameters</li>
<li>Package versioning</li>
<li>Custom SSRS performance reports built into SSMS</li>
<li>Deployment directly from SSDT</li>
</ul>
<p>Fortunately or unfortunately, installation of a new SQL Server instance does not include the creation of the SSISDB Catalog, even if SQL Server Integration Services is included in the installation. For some reason, Microsoft decided to leave that part to the user (luckily, this is a one-time sunk cost).</p>
<p>Once SQL Server installation is completed, you would need to create Catalog using SSMS (see Fig #1) by expanding Management, right clicking on Integration Services Catalogs, and clicking on Create Catalog menu item (see Figure 1).</p>
<figure id="attachment_4514" aria-describedby="caption-attachment-4514" style="width: 352px" class="wp-caption alignnone"><a href="https://sqlsolutionsgroup.com/wp-content/uploads/2020/01/ssis-catalog1.png"><img loading="lazy" decoding="async" class="wp-image-4514 size-full" src="https://sqlsolutionsgroup.com/wp-content/uploads/2020/01/ssis-catalog1.png" alt="ssis catalog" width="352" height="297" srcset="https://sqlsolutionsgroup.com/wp-content/uploads/2020/01/ssis-catalog1.png 352w, https://sqlsolutionsgroup.com/wp-content/uploads/2020/01/ssis-catalog1-300x253.png 300w" sizes="(max-width: 352px) 100vw, 352px" /></a><figcaption id="caption-attachment-4514" class="wp-caption-text"><strong>Figure 1 &#8211; Create Catalog</strong></figcaption></figure>
<h3><strong>Problem</strong></h3>
<p>Once you are done with the full SQL Server installation and ready to create Catalog (SSISDB Catalog to be exact), you might be “greeted” with the following error – “<code>The catalog backup file 'C:\Program Files\Microsoft SQL Server\140\DTS\Binn\SSISDBBackup.bak' could not be accessed. Make sure the database file exists, and the SQL Server service account is able to access it.(Microsoft.SqlServer.IntegrationServices.Common.ObjectModel)</code>“.</p>
<p>I’m sure you were surprised as I am! What? Why would creation of SSISDB Catalog have anything to do with SSISDB database backup (see Fig #2)? Apparently it’s one of the internal steps that Microsoft does behind the scenes when you are installing SQL Server. To be absolutely specific, installation of an Integration Services feature. Strange, right? The real problem is that when you are trying to create an SSISDB Catalog, Microsoft “assumes” that there is database backup file (see Figure 2).</p>
<figure id="attachment_4515" aria-describedby="caption-attachment-4515" style="width: 887px" class="wp-caption aligncenter"><a href="https://sqlsolutionsgroup.com/wp-content/uploads/2020/01/ssis-catalog2.png"><img loading="lazy" decoding="async" class="size-full wp-image-4515" src="https://sqlsolutionsgroup.com/wp-content/uploads/2020/01/ssis-catalog2.png" alt="" width="887" height="357" srcset="https://sqlsolutionsgroup.com/wp-content/uploads/2020/01/ssis-catalog2.png 887w, https://sqlsolutionsgroup.com/wp-content/uploads/2020/01/ssis-catalog2-300x121.png 300w, https://sqlsolutionsgroup.com/wp-content/uploads/2020/01/ssis-catalog2-768x309.png 768w" sizes="(max-width: 887px) 100vw, 887px" /></a><figcaption id="caption-attachment-4515" class="wp-caption-text"><strong>Figure 2 – SSISDBBackup.bak</strong></figcaption></figure>
<h3><strong>Solution</strong></h3>
<p>Apparently, if you forget to enable installation of Integration Services feature, this is the message that you are going to see. The solution involves going back to the installation (see Figure 3) and checking the Integration Services feature.</p>
<figure id="attachment_4516" aria-describedby="caption-attachment-4516" style="width: 789px" class="wp-caption aligncenter"><a href="https://sqlsolutionsgroup.com/wp-content/uploads/2020/01/ssis-catalog3.png"><img loading="lazy" decoding="async" class="size-full wp-image-4516" src="https://sqlsolutionsgroup.com/wp-content/uploads/2020/01/ssis-catalog3.png" alt="" width="789" height="359" srcset="https://sqlsolutionsgroup.com/wp-content/uploads/2020/01/ssis-catalog3.png 789w, https://sqlsolutionsgroup.com/wp-content/uploads/2020/01/ssis-catalog3-300x137.png 300w, https://sqlsolutionsgroup.com/wp-content/uploads/2020/01/ssis-catalog3-768x349.png 768w" sizes="(max-width: 789px) 100vw, 789px" /></a><figcaption id="caption-attachment-4516" class="wp-caption-text"><strong>Figure 3 – SQL Server Installation Center</strong></figcaption></figure>
<figure id="attachment_4517" aria-describedby="caption-attachment-4517" style="width: 899px" class="wp-caption aligncenter"><a href="https://sqlsolutionsgroup.com/wp-content/uploads/2020/01/ssis-catalog4.png"><img loading="lazy" decoding="async" class="wp-image-4517 size-full" src="https://sqlsolutionsgroup.com/wp-content/uploads/2020/01/ssis-catalog4.png" alt="SQL Server Integration Services" width="899" height="546" srcset="https://sqlsolutionsgroup.com/wp-content/uploads/2020/01/ssis-catalog4.png 899w, https://sqlsolutionsgroup.com/wp-content/uploads/2020/01/ssis-catalog4-300x182.png 300w, https://sqlsolutionsgroup.com/wp-content/uploads/2020/01/ssis-catalog4-768x466.png 768w" sizes="(max-width: 899px) 100vw, 899px" /></a><figcaption id="caption-attachment-4517" class="wp-caption-text"><strong>Figure 4 – Integration Services </strong></figcaption></figure>
<p>Once you have Integration Services enabled (see Figure 4) and the installation completed, you should be able to Create Catalog without any problem.</p>
<h3><strong>Disclaimer</strong></h3>
<p>This blog post is based on the following forum discussion <a href="https://www.sqlservercentral.com/forums/topic/missing-ssisdbbackup-bak">https://www.sqlservercentral.com/forums/topic/missing-ssisdbbackup-bak</a>.</p>
<p>The post <a href="https://sqlsolutionsgroup.com/catalog-ssisdb/">Can not create Catalog (SSISDB) due to an error</a> appeared first on <a href="https://sqlsolutionsgroup.com">SQL Solutions Group</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://sqlsolutionsgroup.com/catalog-ssisdb/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
			</item>
	</channel>
</rss>
