Review of SQL Cop for SQL unit testing

Review of SQL Cop for SQL unit testing

Review of SQL Cop for SQL unit testing

SQLShack

SQL Server training Español

Review of SQL Cop for SQL unit testing

September 29, 2017 by Samir Behara SQL unit testing is rising in popularity amongst database developers. The importance of Code Quality in Software Development has increased over the period of time. Everyone wants to follow coding standards and write clean code. However, to timely deliver a product to Business we end up in violating design principles, writing fewer unit tests, increasing code complexity and breaching best practices. This increases the overall Technical Debt of the application and has the potential to halt future development work by creating unplanned work. There are a lot of tools available which can help you to build high-quality software by identifying vulnerabilities at an early stage. Application developers use tools like SonarQube and Analyzers to continuously inspect code quality. But what about database development? Wouldn’t it be awesome to have similar toolset available which can inspect your database code and identify problems with design, performance and security? In this article, we will learn about SQL Unit Testing, Database Static Code Analysis, the benefits of using it in Database Development, SQL Cop and how to use it to identify anti-patterns in your database.

What is SQL Unit Testing

Unit Tests helps you to independently verify a small functionality of your application – be it front end code or database code. Writing SQL Unit Tests is an integral part of the database lifecycle and gives more confidence to developers to push a change to Production. When you write Unit Tests for a stored procedure or function, it should just verify that discrete unit of code. They should be isolated and not be impacted by other tests. The Unit Test suite should confirm that all functionalities work individually.

Why is SQL Unit Testing required

Data is hard to manage and databases are hard to test. Database deployments are far more complicated than application deployment, since you cannot redeploy your code from scratch every time. It cannot be wiped off and recreated during deployments. Having Unit Tests gives you a lot of confidence in making a functionality change and getting an immediate feedback.

Database Lifecycle Management Overview

Database Lifecycle Management is a systematic approach to make database changes more reliable and respond quickly to business demands. With the right set of tools and processes, developers can make complex database changes and deploy them to Production confidently. It is more about identifying defects earlier in the process, preferably prior to code check-in to source control. This is cost-effective and reduces the overhead of handling bugs later in the process. Debugging, Unit Testing and Static Code Analysis empowers a developer towards a smooth delivery.

What is Static Code Analysis

Static Code Analysis is a collection of rules to analyze your source code at compile time to identify potential vulnerabilities, bugs, anti-patterns, refactoring and poor coding practices. It is a great way to automate your code review process, ensure that coding standards are followed and ensure a high quality product.

What is SQL Cop

SQL Cop is a static code analysis tool to automatically detect issues with your database via SQL unit testing. It has a number of code analysis rules that are executed against your database and an analysis report is generated with the detected issues which can be reviewed an actionized. Having a good understanding of these code analysis rules helps you to improve your development skills, since you exactly know the anti-patterns which needs to be avoided.

How to install and use SQL Cop

SQL Cop can be downloaded as a separate executable. There is absolutely no installation required and you can run it as and when you need to do a static code analysis on your database. You can download the executable from the LessThanDot SQLCop website. Once you run the executable, the tool will prompt you to connect to your database instance by providing the Server and Database Name. You will then see the SQL Cop Interface which contains the details of the tool and its usage. On the left hand side, you will see the various categories of issues that SQL Cop can help detect. The rules are categorized under 6 groups – Code, Column, Table/Views, Indexes, Configuration and Health. When you expand any of the rules, you will find all the instances in the code having the issue.

What does the SQL Cop Rules convey

Let’s look at few of the SQL Cop rules and understand the usage recommendations. Procedures without SET NOCOUNT ON When you execute a T-SQL query, SQL Server sends the number of affected rows back to the client. This message is beneficial for the user. However, when you execute a stored procedure performing a lot of updates/deletes/inserts, there is no need of sending the rows affected back to the client. By adding a simple SET NOCOUNT ON, you can suppress this message. This reduces network traffic and enhances the application performance. Doing a SET NOCOUNT ON within stored procedures is considered to be a good practice from performance standpoint. SQL COP scans your entire database code and will identify the stored procedures which did not have NOCOUNT set as ON. Tables without Primary Key The center pane of the SQL Cop tool displays the details around the rule. SQL Cop inspects your database and promptly displays the tables which does not have a primary key. Deprecated Features When Microsoft marks a feature as Deprecated, you should stop using it for new development work and also plan to remove it in near future. After a couple of releases, the deprecated features are discontinued and if you have usages of that syntax it will start throwing errors. Unqualified Joins are a good example of deprecated syntax. SQL Server normally handles ‘old-style’ join syntax quite well in most cases. However, in certain scenarios, the use of an ‘unqualified’ join syntax can cause poor query performance. 12345 select a.id, substring(b.name,1,40) as 'table name', count(colid) as 'count' from syscolumns a, sysobjects bwhere a.id = b.idgroup by a.id, b.name The usage of explicit JOIN syntax is recommended in all cases. SQL Cop helps you to find such deprecated syntax and more in your database code. Fragmented Indexes Fragmented indexes are an overhead for index maintenance. When there are a lot of updates/deletes/inserts on a table over a period of time, indexes tend to get fragmented and can cause performance bottlenecks. SQL Cop helps you to get the list of fragmented indexes in your database, which can then address by doing an index rebuild or reorganize. Varchar size problem When you double click on your selected rule in the left hand pane, SQL Cop will display additional information about the rule, how to detect and correct the issue. What are the additional functionalities that SQL Cop toolbar provides? SQL Cop has a toolbar which provides additional functionalities like – Changing Database Connection Microsoft SQL Server Forum Donate to LessThanDot via Paypal Generate Summary Report Print Report SQL Cop Help

What permissions are required to run SQL Cop

Behind the scene, SQL Cop uses a bunch of Dynamic Management Views to extract the information for the specific rules and display it to the users. To execute Dynamic Management Views, you will need to have VIEW SERVER STATE or VIEW DATABASE STATE permission. If you do not have this access, SQL Cop will prompt you the below message stating the same.

How does SQL Cop work

SQL Cop has a set of predefined rules to identify poor coding practices. It performs static code analysis on your entire database code and finds out all the instances in your database which indicate anti-patterns for database development. To achieve this, it executes T-SQL queries against your database and also captures lots of information from the Dynamic Management Views – which are great resource to monitor the health of the server and diagnose issues. Let’s say you want to look at all the Fragmented Indexes in your database. When you expand the rule, it will fire a query to fetch the impacted indexes. You can look at the SQL Query being executed using SQL Profiler. 12345678910111213141516171819202122 If Exists(Select cmptlevel from master.dbo.sysdatabases Where dbid = db_ID() And cmptlevel > 80) If Exists(Select 1 From fn_my_permissions(NULL, 'DATABASE') WHERE permission_name = 'VIEW DATABASE STATE') Exec('SELECT OBJECT_NAME(OBJECT_ID) + ''.'' + s.name As ProblemItem FROM sys.dm_db_index_physical_stats (DB_ID(), NULL, NULL , NULL, N''LIMITED'') d join sysindexes s ON d.OBJECT_ID = s.id and d.index_id = s.indid Where avg_fragmentation_in_percent >= 30 And OBJECT_NAME(OBJECT_ID) + ''.'' + s.name > '''' And page_count > 1000 Order By Object_Name(OBJECT_ID), s.name') Else Select 'You do not have VIEW DATABASE STATE permissions within this database' As ProblemItemElse Select 'Unable to check index fragmentation when compatibility is set to 80 or below' As ProblemItem

How to configure SQL Profiler for SQL Cop

If you want to capture the queries executed behind the scenes by SQL Cop, you can do that by using SQL Profiler. You can apply a filter to ‘ApplicationName’ property as ‘SQL Cop’ and it will help you to segregate queries executed by this tool only and not capture any other un-related queries running against your database instance.

Does running SQL Cop create temporary performance issues

Running SQL Cop against your database does not create any performance issues. There are no new objects that are created by this tool in your database. Once you provide your database details and connect to the required instance, SQL Cop does not execute all the queries required to verify the rules initially. It follows the pattern of Deferred Execution – which means that the queries are not executed by itself. The queries are executed when the user goes to the left hand pane and expands a particular rule. Let’s say you want to look at the Tables with text/ntext. When you expand this rule, there is a query fired against your database to find out this information. Using SQL Profiler, you can capture the required query – 123456789101112 SELECT SCHEMA_NAME(o.uid) + '.' + o.name + '.' + col.name AS ProblemItemFROM syscolumns col INNER JOIN sysobjects o ON col.id = o.id INNER JOIN systypes ON col.xtype = systypes.xtypeWHERE o.type = 'U' AND OBJECTPROPERTY(o.id, N'IsMSShipped') = 0 AND systypes.name IN ( 'text', 'ntext' )ORDER BY SCHEMA_NAME(o.uid) , o.name , col.name; If all the queries were executed at a single go at the beginning it could have the potential of creating a temporary performance bottleneck. But since the rules are executed selectively as and when the user selects a rule, there is minimal or no impact on performance. However it might be a good idea to be cautious when using SQL Cop on large databases and being aware of the queries that the tool executes.

Usability issues with SQL Cop

I did see some issues while using the tool, where it gets hung when I change my database connection few times. At other times, there was some flickering on the main tool interface which contains the rule details. Also double clicking on the various issues category on the left pane, sometimes does not display the rule details in the main window. In each of the scenarios, closing the tool and restarting it helped. SQL Cop rules are guidelines for identifying anti-patterns in your database code, and there might be some noise/ false positives based on the project you are working one. So, it is highly recommended to properly analyze the findings from this tool and actionize accordingly. From a DevOps perspective, at this point, there is no option to run SQL Cop as part of the automated build. It’s always beneficial to have a static code analyzer tied to your gated check-in process, so that it can reject the code changes if the quality standards are not met.

Conclusion

Code Quality plays an integral part in Software Development Lifecycle. The earlier we identify issues in the process, the easier and cheaper it is to address them. With the combination of SQL unit testing and Static Code Analysis, developers can get an early feedback for their code changes. Tools like SQL Cop are an easy way to identify anti-patterns in your SQL Server database and should be run regularly to improve overall quality of code, adhere to good practices and keep your technical debt in check. SQL Cop rules are integrated with ApexSQL Unit Test – which helps you to write and manage SQL Database unit tests from inside the SQL Server Management Studio. You can add a predefined set of SQL Cop rules to your database for the purpose of static code analysis.
Author Recent Posts Samir BeharaSenior Developer at EBSCO IndustriesSamir Behara is a Solution Architect with EBSCO Industries and builds software solutions using cutting edge technologies. He is a Microsoft Data Platform MVP with over 13 years of IT experience working on large-scale enterprise applications involving complex business functions, web integration, and data management in various domains like Insurance, Manufacturing and Publishing.

Samir is a frequent speaker at conferences such as PASS Summit, IT/Dec Connections, CodeStock, SQL Saturdays and CodeCamps. He is the Co-Chapter Lead of the Steel City SQL Server UserGroup, Birmingham, AL. He is the author of www.dotnetvibes.com

View all posts by Samir Behara Latest posts by Samir Behara (see all) What’s new in SQL Server Management Studio 17.4; SQL Vulnerability assessment and more - December 26, 2017 Review of SQL Cop for SQL unit testing - September 29, 2017 Querying Microsoft SQL Server 2012/2014 – Preparing for Exam 70-461 - September 8, 2017

Related posts

Fundamentals of Test-Driven Database Development (TDDD) with tSQLt unit testing Why you should cleverly name Database Objects for SQL Unit Testing SQL Unit testing with the tSQLt framework and SQL Server Database Project integration tSQLt – A Forgotten Treasure in Database Unit Testing Three Standard SQL Unit Tests you can write against any Stored Procedure 2,687 Views

Follow us

Popular

SQL Convert Date functions and formats SQL Variables: Basics and usage SQL PARTITION BY Clause overview Different ways to SQL delete duplicate rows from a SQL Table How to UPDATE from a SELECT statement in SQL Server SQL Server functions for converting a String to a Date SELECT INTO TEMP TABLE statement in SQL Server SQL WHILE loop with simple examples How to backup and restore MySQL databases using the mysqldump command CASE statement in SQL Overview of SQL RANK functions Understanding the SQL MERGE statement INSERT INTO SELECT statement overview and examples SQL multiple joins for beginners with examples Understanding the SQL Decimal data type DELETE CASCADE and UPDATE CASCADE in SQL Server foreign key SQL Not Equal Operator introduction and examples SQL CROSS JOIN with examples The Table Variable in SQL Server SQL Server table hints – WITH (NOLOCK) best practices

Trending

SQL Server Transaction Log Backup, Truncate and Shrink Operations Six different methods to copy tables between databases in SQL Server How to implement error handling in SQL Server Working with the SQL Server command line (sqlcmd) Methods to avoid the SQL divide by zero error Query optimization techniques in SQL Server: tips and tricks How to create and configure a linked server in SQL Server Management Studio SQL replace: How to replace ASCII special characters in SQL Server How to identify slow running queries in SQL Server SQL varchar data type deep dive How to implement array-like functionality in SQL Server All about locking in SQL Server SQL Server stored procedures for beginners Database table partitioning in SQL Server How to drop temp tables in SQL Server How to determine free space and file size for SQL Server databases Using PowerShell to split a string into an array KILL SPID command in SQL Server How to install SQL Server Express edition SQL Union overview, usage and examples

Solutions

Read a SQL Server transaction logSQL Server database auditing techniquesHow to recover SQL Server data from accidental UPDATE and DELETE operationsHow to quickly search for SQL database data and objectsSynchronize SQL Server databases in different remote sourcesRecover SQL data from a dropped table without backupsHow to restore specific table(s) from a SQL Server database backupRecover deleted SQL data from transaction logsHow to recover SQL Server data from accidental updates without backupsAutomatically compare and synchronize SQL Server dataOpen LDF file and view LDF file contentQuickly convert SQL code to language-specific client codeHow to recover a single table from a SQL Server database backupRecover data lost due to a TRUNCATE operation without backupsHow to recover SQL Server data from accidental DELETE, TRUNCATE and DROP operationsReverting your SQL Server database back to a specific point in timeHow to create SSIS package documentationMigrate a SQL Server database to a newer version of SQL ServerHow to restore a SQL Server database backup to an older version of SQL Server

Categories and tips

►Auditing and compliance (50) Auditing (40) Data classification (1) Data masking (9) Azure (295) Azure Data Studio (46) Backup and restore (108) ►Business Intelligence (482) Analysis Services (SSAS) (47) Biml (10) Data Mining (14) Data Quality Services (4) Data Tools (SSDT) (13) Data Warehouse (16) Excel (20) General (39) Integration Services (SSIS) (125) Master Data Services (6) OLAP cube (15) PowerBI (95) Reporting Services (SSRS) (67) Data science (21) ►Database design (233) Clustering (16) Common Table Expressions (CTE) (11) Concurrency (1) Constraints (8) Data types (11) FILESTREAM (22) General database design (104) Partitioning (13) Relationships and dependencies (12) Temporal tables (12) Views (16) ▼Database development (418) Comparison (4) Continuous delivery (CD) (5) Continuous integration (CI) (11) Development (146) Functions (106) Hyper-V (1) Search (10) Source Control (15) SQL unit testing (23) Stored procedures (34) String Concatenation (2) Synonyms (1) Team Explorer (2) Testing (35) Visual Studio (14) DBAtools (35) DevOps (23) DevSecOps (2) Documentation (22) ETL (76) ►Features (213) Adaptive query processing (11) Bulk insert (16) Database mail (10) DBCC (7) Experimentation Assistant (DEA) (3) High Availability (36) Query store (10) Replication (40) Transaction log (59) Transparent Data Encryption (TDE) (21) Importing, exporting (51) Installation, setup and configuration (121) Jobs (42) ►Languages and coding (686) Cursors (9) DDL (9) DML (6) JSON (17) PowerShell (77) Python (37) R (16) SQL commands (196) SQLCMD (7) String functions (21) T-SQL (275) XML (15) Lists (12) Machine learning (37) Maintenance (99) Migration (50) Miscellaneous (1) ►Performance tuning (869) Alerting (8) Always On Availability Groups (82) Buffer Pool Extension (BPE) (9) Columnstore index (9) Deadlocks (16) Execution plans (125) In-Memory OLTP (22) Indexes (79) Latches (5) Locking (10) Monitoring (100) Performance (196) Performance counters (28) Performance Testing (9) Query analysis (121) Reports (20) SSAS monitoring (3) SSIS monitoring (10) SSRS monitoring (4) Wait types (11) ►Professional development (68) Professional development (27) Project management (9) SQL interview questions (32) Recovery (33) Security (84) Server management (24) SQL Azure (271) SQL Server Management Studio (SSMS) (90) SQL Server on Linux (21) ►SQL Server versions (177) SQL Server 2012 (6) SQL Server 2016 (63) SQL Server 2017 (49) SQL Server 2019 (57) SQL Server 2022 (2) ►Technologies (334) AWS (45) AWS RDS (56) Azure Cosmos DB (28) Containers (12) Docker (9) Graph database (13) Kerberos (2) Kubernetes (1) Linux (44) LocalDB (2) MySQL (49) Oracle (10) PolyBase (10) PostgreSQL (36) SharePoint (4) Ubuntu (13) Uncategorized (4) Utilities (21) Helpers and best practices BI performance counters SQL code smells rules SQL Server wait types © 2022 Quest Software Inc. ALL RIGHTS RESERVED. GDPR Terms of Use Privacy
Share:
0 comments

Comments (0)

Leave a Comment

Minimum 10 characters required

* All fields are required. Comments are moderated before appearing.

No comments yet. Be the first to comment!