{"id":1734,"date":"2013-12-10T00:00:00","date_gmt":"2013-12-10T00:00:00","guid":{"rendered":"https:\/\/test.simple-talk.com\/uncategorized\/sql-enlight-for-sql-server-management-studio\/"},"modified":"2021-05-11T15:57:22","modified_gmt":"2021-05-11T15:57:22","slug":"sql-enlight-for-sql-server-management-studio","status":"publish","type":"post","link":"https:\/\/www.red-gate.com\/simple-talk\/databases\/sql-server\/tools-sql-server\/sql-enlight-for-sql-server-management-studio\/","title":{"rendered":"SQL Enlight for SQL Server Management Studio"},"content":{"rendered":"<div id=\"pretty\">\n<p class=\"start\">Probably the greatest cause of database performance problems is badly-written  code. A fairly significant pro&#194;&#173;por&#194;&#173;tion of code problems are easily-identifiable &#8220;<a href=\"https:\/\/www.simple-talk.com\/blogs\/2010\/11\/22\/listing-common-sql-code-smells\/\">code  smells<\/a>&#8221; that are well-known and are easily avoided. Yet, large amounts of code include them. Yes, you can review all  the code that passes through your hands before it ends up in your production system; or &#160;you  can begin to automate the process. This is where SQL Enlight for SSMS comes into play.<\/p>\n<p><a href=\"http:\/\/www.ubitsoft.com\/products\/sqlenlight-for-ssms\/index.php\">SQL  Enlight for SSMS<\/a> is a code analysis tool from <a href=\"http:\/\/www.ubitsoft.com\/\">UbitSoft<\/a>. The basic idea is  simple. You first establish a set of best practices and guidelines for your code, or adopt the existing standards: Then  you find &#160;a way of &#160;ensuring that your code  meets those standards and guidelines. SQL Enlight works within SQL Server Management Studio (SSMS) to provide you with a  mechanism for running these checks on your existing databases. It also supplies a way of checking databases from a  command line. &#160;With the guidelines, and a process for checking your SQL code, &#160;you can then automate the process of auditing your systems to ensure that they  comply with your coding standards, <a href=\"http:\/\/tsqlsmells.codeplex.com\/\">using, for example, PowerShell<\/a>.  <\/p>\n<p>This tool also represents a new initiative from Red Gate Software. We&#8217;ve long  been working within SSMS with various tools like the indispensable SQL Prompt or SQL Search. But we&#8217;ve recognized a need  for a wider set of tools that allow for more specialized support within SSMS. So, we&#8217;re establishing the <a href=\"http:\/\/www.red-gate.com\/ssmsecosystem\">SSMS Ecosystem<\/a>. <a href=\"https:\/\/www.simple-talk.com\/blogs\/2013\/11\/22\/introducing-the-red-gate-ssms-ecosystem\/\">Here&#8217;s a blog post<\/a>  explaining the concept in more detail. UbitSoft is one of the very first organization to jump at this new initiative.  Let&#8217;s take a look at the work they&#8217;ve done.<\/p>\n<h1>Best Practices and Coding Guidelines<\/h1>\n<p>UbitSoft have spent years collecting all the published good advice, warnings of  deprecation, and SQL practices that cause bugs or performance problems. &#160;If you  were to change your code until it passed on all counts, you&#8217;d be spending a lot of time on doing things that may have no  effect on the code. You&#8217;ll certainly want to know about, and address, a lot of these rules, such as the use of coding  practices that slow performance down. You&#8217;ll probably need to get that code refactored. You may receive other advice  with a shrug. &#160;Code Smells merely indicate that you need to check in more detail.  It could be that the code is fine, perhaps doing something unusual, but perfectly legitimate in the circumstances. There  will be advice you don&#8217;t agree with, other advice you merely want to know about without reacting, code smells that makes  you frown, and anti-patterns that you&#8217;ve really got to fix before it can get to production.&#160; Each shop is different, but SQL Enlight allows you to decide what&#8217;s important for you.<\/p>\n<h1>Download, Installation, Configuration<\/h1>\n<p>You can get a 14 day free trial from UbitSoft to check out the usefulness of  this software for yourself. Following the links above to the download page, the process is extremely straightforward. If  you click on the download links and you&#8217;ll get an executable. By running it, I had a flawless install to my machine.  When I opened up SSMS for the first time (it must be closed during the installation), I couldn&#8217;t immediately see  anything new. Then I saw a menu choice at the top of the screen:<\/p>\n<p class=\"illustration\"><img loading=\"lazy\" decoding=\"async\" height=\"233\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/imported\/1910-clip_image001.png\" width=\"337\" alt=\"1910-clip_image001.png\" \/><\/p>\n<p>The installation of SQL Enlight went quite smoothly as you see. I could have  accepted the defaults for the configuration, but I wanted to see what sorts of behavior I could control, so I  immediately opened the Options screen.<\/p>\n<p>The first tab on the Options screen is not for configuring the behavior of the  software. Instead it&#8217;s the listing of all possible Rules. I&#8217;ll get to those in a minute. The second options screen, &#8216;<i>Options&#8217;<\/i>,  can be accessed by clicking. Now, it&#8217;s much more likely that you&#8217;ll set the Options once and then never go back to them  with most of the work you&#8217;ll be doing within the Rules. But, accessing the Rules through the &#8216;<i>Options<\/i>&#8216;  menu and then having to do extra work to then get to the actual options seems to be slightly counter-intuitive.  <\/p>\n<p>The first screen in &#8216;<i>Options&#8217;<\/i> allows you to set general behaviors, such as importing or exporting rules, and setting up regular  updates to the standard set of rules:<\/p>\n<p class=\"illustration\"><img loading=\"lazy\" decoding=\"async\" height=\"335\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/imported\/1910-clip_image003.png\" width=\"586\" alt=\"1910-clip_image003.png\" \/><\/p>\n<p>The next tab is for setting the <i>&#8216;Context&#8217;<\/i>,  the behavior, of SQL Enlight. The first option is for &#8216;<i>Analysis Context Load Mode<\/i>&#8216;  with two choices, &#8216;<i>Basic<\/i>&#8216; or &#8216;<i>Full<\/i>&#8216;.  I read the descriptions of each of these modes and still didn&#8217;t completely understand what it meant. When I &#160;looked it up in the documentation, I found that the&#8217;<i>Basic<\/i>&#8216;  listing covered most of the standard database objects that you would expect while &#8216;<i>Full&#8217;<\/i>  added in a number of additional object types:<\/p>\n<ul>\n<li>Message Types<\/li>\n<li>Services<\/li>\n<li>Routes<\/li>\n<li>SymmetricKeys<\/li>\n<li>AsymmetricKeys<\/li>\n<li>Extended Properties<\/li>\n<li>Event Notifications<\/li>\n<\/ul>\n<p>Now it makes sense. Instead of saying &#160;&#8217;<i>Only  the most commonly used schema information is loaded during analysis<\/i>&#8216; I&#8217;d like to see something more clear such as &#8216;<i>Standard  set of database\/server objects used for analysis<\/i>&#8216; or something along those lines. You can see the options in the  screen below. I didn&#8217;t understand what &#8216;<i>schema information&#8217;<\/i> and &#8216;<i>loading&#8217;<\/i>  meant in the context of static code analysis until I saw the listing of objects.<\/p>\n<p>You also get the means to set up default connections for test-analysis and for  when a script will be valided. You can enable or disable the automatic validation by SQL Server prior to running SQL  Enlight. That&#8217;s a nice touch:<\/p>\n<p class=\"illustration\"><img loading=\"lazy\" decoding=\"async\" height=\"448\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/imported\/1910-clip_image005.png\" width=\"586\" alt=\"1910-clip_image005.png\" \/><\/p>\n<p>The final tab allows you to control the behavior of SQLEnlight within SSMS.  First, you can decide if you want the automated analysis to occur before either the execution or parse of the commands  (that&#8217;s still independent of SQL Server behavior as was noted in the previous tab). I&#8217;ve enabled both for the  experiment. You also get to decide which rules are applied. I&#8217;ve got mine set to the default which is for all rules that  are enabled; Active Rules. You could instead decide which rules you want to run on the fly. <\/p>\n<p>The tool uses an execution context, set on the preceding screen, to determine  appropriate use of the code during its evaluations. You can disable that context information here. You can also set  where, and if, it caches disk information.<\/p>\n<p class=\"illustration\"><img loading=\"lazy\" decoding=\"async\" height=\"381\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/imported\/1910-clip_image007.png\" width=\"586\" alt=\"1910-clip_image007.png\" \/><\/p>\n<p>That&#8217;s it. With the system configured, it&#8217;s time to check out the behavior  within SSMS.<\/p>\n<h1>Analysis<\/h1>\n<p>SQL Enlight will run its analysis in two different ways; from the GUI &#8211; running  against your existing code and structures, and automated &#8211; another type of static analysis run from the command line for  automation purposes. <\/p>\n<p>But, before we can run the analysis, let&#8217;s talk about what it is that we are  going to analyze, the Rules.<\/p>\n<h2>The Rules<\/h2>\n<p>SQL Enlight comes with a standard set of rules. You can see these rules by going  through the &#8216;<i>Options&#8217; <\/i>menu choice. They are a very thorough set of standards that are fairly well established within the  SQL Server community, so you can&#8217;t go wrong just using their defaults. Let&#8217;s walk through some of what we have  available.<\/p>\n<p>First, the rules themselves are broken down into groups:<\/p>\n<p class=\"illustration\"><img loading=\"lazy\" decoding=\"async\" height=\"140\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/imported\/1910-clip_image009.png\" width=\"211\" alt=\"1910-clip_image009.png\" \/><\/p>\n<p>The great thing about having these groups is that you can use them to determine  what checks you run against your structure and your code. You can run all active rules any time you want. You can also  run any individual rule any time you want, but, you may not feel the need to regularly &#160;run,  say, the Maintenance Rules on servers because it&#8217;s unlikely that your maintenance routines, once established, mess up  very much. However, you will want to run Performance or Naming rules on a regular basis, so you can decide immediately  which ones you want to run.<\/p>\n<p>Within the groups, you have a set of rules that can be enabled or disabled. The  rules themselves cover a whole slew of different options. Let&#8217;s just look at one example to give you an idea of how all  the rules will work. There is a rule called &#8220;<i>SA0007 : Pattern starting with &#8220;%&#8221; in LIKE predicate.&#8221;<\/i> This is a great check in your code. If you have a  query that looks something like this:<\/p>\n<pre>SELECT... FROM... WHERE x.MyVal LIKE '%SomeValue%';<\/pre>\n<p>You will inevitably get only index scans on that table for that query, so this  rule checks for this antipattern &#160;within your code. It&#8217;s an excellent idea. By  default this rule is enabled. You can choose to disable it. Further, some rules have parameters that let you modify  their behavior. This is just such a rule. It looks for the existence of a comment just before the statement using the  beginning wild card type of search. If there is a comment, the code analysis assumes that you have an explanation why  you want to violate the rule in this instance and will skip the rule. <\/p>\n<p class=\"illustration\"><img loading=\"lazy\" decoding=\"async\" height=\"453\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/imported\/1910-clip_image011.png\" width=\"586\" alt=\"1910-clip_image011.png\" \/><\/p>\n<p>You can create your own rules if you&#8217;re so inclined. Currently, that is a  somewhat difficult process that I don&#8217;t want to document for this simple review. You can also edit, save or remove rules  from your system. The GUI also gives you the ability to search for specific rules.<\/p>\n<p>You can look through the documentation to see all the different rules. You can  also browse through them using the GUI. Let&#8217;s see the rules in action.<\/p>\n<h2>SSMS Analysis<\/h2>\n<p>You have different approaches to get started with a static analysis session with  SQL Enlight. I would assume that you are usually simply going to right-click on any given database and start the process  of analyzing it by making a choice from the context menu:<\/p>\n<p class=\"illustration\"><img loading=\"lazy\" decoding=\"async\" height=\"186\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/imported\/1910-clip_image013.png\" width=\"591\" alt=\"1910-clip_image013.png\" \/><\/p>\n<p>For this test of the software, I&#8217;ll run the analysis of all active rules against  my instance of AdventureWorks2012. I haven&#8217;t cleaned it up from a series of tests recently, so, in addition to any  issues that Microsoft may have introduced, I should have one or two poor choices on display. When I select to begin the  analysis of all rules, a modal window is opened showing the current status of the evaluations. I also see a script  window open that creates a script of all the objects on the system that need to be evaluated from a code window. These  consist primarily of code elements of the database such as views, stored procedures, triggers and functions. I&#8217;m not  sure why that gets created and I don&#8217;t have to keep it around to see the output which appears in a window at the bottom  of my screen:<\/p>\n<p class=\"illustration\"><img loading=\"lazy\" decoding=\"async\" height=\"215\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/imported\/1910-clip_image015-630x215.jpg\" width=\"630\" alt=\"1910-clip_image015-630x215.jpg\" \/><\/p>\n<p>For my one database I have over 600 warnings from the evaluations of the rules.  And they&#8217;re interesting. For example, above you see a series of suggested missing foreign keys on a<code> table,MyBusinessEntityAddress<\/code>. Funny enough, it&#8217;s a table where I demonstrate the importance of enforced foreign keys  for the optimizer. In short, these are real problems in my database. Code segments will immediately show up back in the  scripted window, where you can highlight the suggested error and go straight to it within the code of the T-SQL window.<\/p>\n<p>That is one thing that could prove to be a major problem for very large  databases because you can create a script that is too large to open within SSMS. But, as configured, you get a quick  view of the code that is problematic based on the analysis you ran.<\/p>\n<p>However, that detail aside, this is a fantastic collection of rules that will  immediately identify a large amount of very easy-to-fix issues in your system.<\/p>\n<h2>Dynamic Checks<\/h2>\n<p>If you enable SQL Enlight through the &#8216;<i>options<\/i>&#8216;  screen to check your queries as you execute or compile them, you get even more from the tool. In fact, I&#8217;d go so far as  to suggest doing this as a standard part of pre-checkin of all code. Just as you would write a unit test and ensure that  your code passes the unit test before &#160;checking it into source control, you could  also have it run through your SQL Enlight checks. I have a piece of code that I wrote for AdventureWorks2012  <\/p>\n<pre class=\"theme:ssms2012 lang:tsql\">SELECT&#160; *\nFROM&#160;&#160;&#160; Sales.SalesOrderHeader AS soh\n&#160;&#160;&#160;&#160;&#160;&#160;&#160; JOIN Sales.SalesOrderDetail AS sod ON sod.SalesOrderID = soh.SalesOrderID\nWHERE&#160;&#160; soh.Comment LIKE '%Dude%'\n<\/pre>\n<p>It&#8217;s not that important what the code does or even if it&#8217;s working for the  purposes of this review. But, when I execute the code, I immediately get the SQL Enlight window showing that it&#8217;s doing  checks against my T-SQL and then this window:<\/p>\n<p class=\"illustration\"><img loading=\"lazy\" decoding=\"async\" height=\"185\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/imported\/1910-clip_image017.png\" width=\"459\" alt=\"1910-clip_image017.png\" \/><\/p>\n<p>With that you get the opportunity to stop and fix the issues that have been  identified. In the case of the sample code above, there a couple of issues, one minor and one potentially a huge issue:<\/p>\n<p class=\"illustration\"><img loading=\"lazy\" decoding=\"async\" height=\"53\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/imported\/1910-clip_image019.png\" width=\"571\" alt=\"1910-clip_image019.png\" \/><\/p>\n<p>In addition to showing the above list, the T-SQL edit window is updated to show  you exactly where all the issues can be found:<\/p>\n<p class=\"illustration\"><img loading=\"lazy\" decoding=\"async\" height=\"80\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/imported\/1910-clip_image021.png\" width=\"631\" alt=\"1910-clip_image021.png\" \/><\/p>\n<p>Then it&#8217;s just a matter of going back through the code and making the  adjustments where appropriate. This is how you should be able to manage your T-SQL code within SSMS just as if it were &#160;a true Integrated Development Environment (IDE). <\/p>\n<h2>Command Line<\/h2>\n<p>While it is very useful to be able to simply browse the warnings and errors  generated through SSMS, you&#8217;ll need a lot more than this &#160;if you&#8217;re planning on  creating any type of automation to your build and deployment processes, especially when it comes to checking on all  those coding standards and guidelines &#160;tthat SQL Enlight can audit for you. That&#8217;s  where the command-line utility comes into play.<\/p>\n<p>Because you have a command-line application available, you can run this as part  of&#160; just about any process you want. You can call it from PowerShell. You can  use the SQL Agent to schedule jobs. You can incorporate it into a continuous deployment process. The command line itself  is reasonably straight forward:<\/p>\n<pre>Enlight.exe command [parameters] [\/quite \/nologo]<\/pre>\n<p>The commands you have available are:<\/p>\n<ul>\n<li>Analyze<\/li>\n<li>Configure<\/li>\n<li>License<\/li>\n<li>analysiscontext<\/li>\n<\/ul>\n<p>The one we&#8217;re primarily concerned with will be <b>Analyze<\/b>.<\/p>\n<p>As with any software, there&#8217;s a little more to it than immediately appears. The  documentation is a little light, so I had to do a series of experiments and exchange a couple of emails with UbitSoft,  but this command line worked:<\/p>\n<pre>Enlight analyze \/targettype:serverobjects \/database:AdventureWorks2012 \/objecttype:database \/objectname:* \/report:\"c:\\reports\\mydb.xml\" \/server:DOJO\\RANDORI <\/pre>\n<p>Let&#8217;s break that down just a little. Some of the options are very  straightforward, <b>server<\/b> and <b>database<\/b>  shouldn&#8217;t need much explanation. You can use a trusted connection or supply a user name and password. The <b>Target<\/b> Type can only be files or server-objects. This means that you can run  the analysis against a set of files, probably after you check them out of source control, just for an example. I&#8217;m  running it directly against a server in this example. You can also limit the objects accessed through the <b>ObjectType<\/b> designator:<\/p>\n<ul>\n<li>Server<\/li>\n<li>Server Trigger<\/li>\n<li>View<\/li>\n<li>Database<\/li>\n<li>Dml Trigger<\/li>\n<li>Database Trigger<\/li>\n<li>User Defined Function<\/li>\n<li>Database Prgogrammability Object<\/li>\n<li>Stored Procedure<\/li>\n<\/ul>\n<p>You can also supply a specific <b>Object  Name<\/b>, but in this instance, I went after all the objects.<\/p>\n<p>This is just about perfect. It&#8217;s everything I would want. The one, the only,  issue I have with it is that the output is XML only, but both PowerShell and TSQL can deal with that. Here&#8217;s a sample  output:<\/p>\n<pre class=\"theme:ssms2012 lang:tsql\">&lt;Target Name=&amp;\"[dbo].[ufnGetContactInformation]\" Type=\"Function\"&gt;\n&#160;&#160; &lt;Issue Rule=\"EX0018\" Type=\"RuleViolation\" Message=\"EX0018 : Missing Index&#160; with impact 88.1453 on table [Sales].[Customer] for columns([PersonID],[StoreID]).\" Level=\"Warning\" Line=\"61\" Offset=\"1\" \/&gt;\n&#160;&#160; &lt;Issue Rule=\"EX0018\" Type=\"RuleViolation\" Message=\"EX0018 : Missing Index&#160; with impact 88.1482 on table [Sales].[Customer] for columns([PersonID],[StoreID]).\" Level=\"Warning\" Line=\"61\" Offset=\"1\" \/&gt;\n&#160;&#160; &lt;Issue Rule=\"SA0010\" Type=\"RuleViolation\" Message=\"SA0010 : Use TRY..CATCH or check the @@ERROR variable after executing data manipulation statement.\" Level=\"Warning\" Line=\"20\" Offset=\"3\" \/&gt;\n&#160;&#160; &lt;Issue Rule=\"SA0010\" Type=\"RuleViolation\" Message=\"SA0010 : Use TRY..CATCH or check the @@ERROR variable after executing data manipulation statement.\" Level=\"Warning\" Line=\"31\" Offset=\"3\" \/&gt;\n&#160;&#160; &lt;Issue Rule=\"SA0010\" Type=\"RuleViolation\" Message=\"SA0010 : Use TRY..CATCH or check the @@ERROR variable after executing data manipulation statement.\" Level=\"Warning\" Line=\"46\" Offset=\"3\" \/&gt;\n&#160;&#160; &lt;Issue Rule=\"SA0010\" Type=\"RuleViolation\" Message=\"SA0010 : Use TRY..CATCH or check the @@ERROR variable after executing data manipulation statement.\" Level=\"Warning\" Line=\"61\" Offset=\"3\" \/&gt;\n&#160;&#160; &lt;Issue Rule=\"SA0011\" Type=\"RuleViolation\" Message=\"SA0011 : SELECT * in stored procedures, views and table-valued functions.\" Level=\"Warning\" Line=\"18\" Offset=\"19\" \/&gt;\n&#160;&#160; &lt;Issue Rule=\"SA0011\" Type=\"RuleViolation\" Message=\"SA0011 : SELECT * in stored procedures, views and table-valued functions.\" Level=\"Warning\" Line=\"27\" Offset=\"19\" \/&gt;\n&#160;&#160; &lt;Issue Rule=\"SA0011\" Type=\"RuleViolation\" Message=\"SA0011 : SELECT * in stored procedures, views and table-valued functions.\" Level=\"Warning\" Line=\"42\" Offset=\"19\" \/&gt;\n&#160;&#160; &lt;Issue Rule=\"SA0011\" Type=\"RuleViolation\" Message=\"SA0011 : SELECT * in stored procedures, views and table-valued functions.\" Level=\"Warning\" Line=\"57\" Offset=\"19\" \/&gt;\n&#160;&#160; &lt;Issue Rule=\"SA0020\" Type=\"RuleViolation\" Message=\"SA0020 : Always use a column list in INSERT statements.\" Level=\"Warning\" Line=\"20\" Offset=\"3\" \/&gt;\n&#160;&#160; &lt;Issue Rule=\"SA0020\" Type=\"RuleViolation\" Message=\"SA0020 : Always use a column list in INSERT statements.\" Level=\"Warning\" Line=\"31\" Offset=\"3\" \/&gt;\n&#160;&#160; &lt;Issue Rule=\"SA0020\" Type=\"RuleViolation\" Message=\"SA0020 : Always use a column list in INSERT statements.\" Level=\"Warning\" Line=\"46\" Offset=\"3\" \/&gt;\n&#160;&#160; &lt;Issue Rule=\"SA0020\" Type=\"RuleViolation\" Message=\"SA0020 : Always use a column list in INSERT statements.\" Level=\"Warning\" Line=\"61\" Offset=\"3\" \/&gt;\n&#160;&#160; &lt;Issue Rule=\"SA0078\" Type=\"RuleViolation\" Message=\"SA0078 : Statement is not terminated with semicolon.\" Level=\"Warning\" Line=\"67\" Offset=\"5\" \/&gt;\n&lt;\/Target&gt;\n<\/pre>\n<p>What I like about it is that each object has the full output of all rules, so you can  see that this function, <b>ufnGetContactInformation<\/b>, has 15 different violations  of the rules. There are several violations of certain rules like <i>&#8216;Always use a  column list in INSERT statements<\/i>&#8216; Which had four different instances within the query. But the fact that I either  have to browse XML or write a report mechanism against it is a pain. Sorry, but there it is. I&#8217;m in love with the  concept, but I&#8217;d just like to see a little easier access to the results. Maybe a standard output such as JUnit so that  continuous integration tooling can output standard reports from the results? <\/p>\n<p>But, that&#8217;s really something of a nit that I&#8217;m picking. The main point is that I  can completely automate validation of my code as part of any deployment process I have set up. That&#8217;s a huge win. Add in  the fact that I can also create my own customized code checks and suddenly my deployment processes are more efficient  than ever. I&#8217;ll go it one better. UbitSoft had the foresight to add in MSBuild and Nant tasks to assist you with your  deployment automation above and beyond what&#8217;s supplied through just a command line. That truly makes this tool useful.<\/p>\n<h1>Conclusion<\/h1>\n<p>This is a very useful tool. I love the concept and I love most of the execution.  I think the interface and the command line have a few rough spots that can be fixed over time. They&#8217;re not show  stoppers, just irritants. There&#8217;s no escaping the utility provided by this tool, to be able to check such a wide variety  of issues in such an easy manner, and one that you can automate. <\/p>\n<p>It is so useful to be able to build it right into my  automated deployment scripts for a much more useful process overall. I can decide which rules that I want to run when  and can even, to an extent, &#160;change the way that the rules are applied. This makes  for some very flexible auditing mechanisms. <\/p>\n<p>While you&#8217;re likely to hit a few snags with the documentation and the  slightly inscrutable interface, I&#8217;m positive that you&#8217;ll find the rest of the experience so far outweighs the minor  shortcomings that you&#8217;ll be incorporating SQL Enlight into your own development environment in no time.<\/p>\n<\/p><\/div>\n","protected":false},"excerpt":{"rendered":"<p>The process of doing SQL code-reviews used to be tedious and error-prone. Until SQL Enlight, it was a process that was difficult to automate for release and deployment. As it is now both a Command-line utility and an SSMS add-in, the database developer can see immediately the parts of the code that would raise eyebrows with the vigilant production DBA.&hellip;<\/p>\n","protected":false},"author":221792,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[143532],"tags":[4168,4150,4151,4213],"coauthors":[],"class_list":["post-1734","post","type-post","status-publish","format-standard","hentry","category-tools-sql-server","tag-database","tag-sql","tag-sql-server","tag-sql-tools"],"acf":[],"_links":{"self":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/1734","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/users\/221792"}],"replies":[{"embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/comments?post=1734"}],"version-history":[{"count":6,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/1734\/revisions"}],"predecessor-version":[{"id":90953,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/1734\/revisions\/90953"}],"wp:attachment":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/media?parent=1734"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/categories?post=1734"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/tags?post=1734"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/coauthors?post=1734"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}