DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Related

  • Best Practices for Exchange Server 2019 Storage
  • How to Move System Databases to Different Locations in SQL Server on Linux
  • Using the PostgreSQL Pager With MariaDB Xpand
  • A Beginner's Guide to Back-End Development

Trending

  • Designing API-First EMR Architectures in .NET: Enabling Modular Growth in Compliance-Driven Systems
  • What Nobody Tells You About Multimodal Data Pipelines for AI Training
  • LLM Agents and Getting Started with Them
  • AI Paradigm Shift: Analytics Without SQL
  1. DZone
  2. Data Engineering
  3. Databases
  4. Scanning a TSQL Project With SonarQube

Scanning a TSQL Project With SonarQube

Learn how to scan TSQL code using SonarQube and receive reports on metrics to detect and locate performance issues.

By 
Greta Rd user avatar
Greta Rd
·
Aug. 28, 18 · Tutorial
Likes (5)
Comment
Save
Tweet
Share
19.5K Views

Join the DZone community and get the full member experience.

Join For Free

daIn this article, I will demonstrate how to get TSQL code scanned and reported in SonarQube with the open-source sonar-tsql-plugin so you can track

  • Code metrics
  • Static code issues found by SQL Code Guard and Microsoft
  • Code coverage results reported by tSQLt and SQLCover
  • Code duplications

I will use an example project which can be found at tsql-example-project.zip. It contains scripts of a database with two tables, scalar function, and two tSQLt tests checking if a function works correctly.

I will use a Windows operating system and PowerShell scripts to configure the dependencies. However, some of the plugin’s features can run on Linux OS as well. In this article, a locally running SonarQube instance will be used. If you want to run all example scripts on your machine, you will need to have at least msbuild and SQL Server Data Tools installed. If you don't, then you will be able to use only a subset of the features discussed here.

After finishing all the steps described below, you will see a number of issues found, code coverage achieved, and other metrics in your SonarQube dashboard. The final result could look like as depicted in the figure below.

TSQL example project's dashboard in SonarQube

In order to achieve this, follow the steps below on the SonarQube server side and on the machine from which you are going run sonar-scanner.

SonarQube's Server-Side Changes

In order to get TSQL code analyzed, you will need to install the plugin on the SonarQube server. If you don't have the server yet, you can download it from their site. The steps below describe how to install a plugin on the SonarQube server.

Step 1: Download and install the latest version of sonar-tsql-plugin.jar from GitHub.

Step 2: Copy the JAR file into your SonarQube's extensions/downloads folder, as displayed in the image below.

Installing plugin on SonarQube

Step 3: Restart your SonarQube instance. After this, if you navigate to the SonarQube web interface in the Rules section, you should see the TSQL language with a few rules repositories.

TSQL rules in SonarQube

That's all for the server-side changes. Now, let's check out the build machine changes from which you are going to execute sonar-scanner to get the results into SonarQube.

Build Machine Changes

In order to get SQLCodeGuard, SSDT code analysis, and SQLCover findings reported to SonarQube, you need to install the following on the build machine from which you are going to run sonar-scanner:

  • MSBuild
  • SSDT
  • SQLCodeGuard
  • SQLCover

The installation of some of these prerequisites is discussed in Step 1.

In addition to this, if you are going to use the tSQLt framework for tests, you will need to deploy and publish a database. This is described in steps 2 and 3.

If you already have the aforementioned prerequisites and tSQLt sorted or you don't want to use them, you can go straight to Step 4.

If you have not yet downloaded the example project, you need to download it from GitHub and extract it into your file system. It contains a few scripts facilitating changes which are discussed below. The project's structure is as follows:

  • src – example database source code
  • 00-installTools.ps1- Powershell script to download and extract SQLCodeGuard, SQLCover, and sonar-scanner to example project's tools directory
  • 01-executeDBChanges.ps1 – Powershell script to sort tSQLt onto MSSQL database
  • 02-runSonar.ps1 – Powershell script which builds sample database code, runs tSQLt tests and executes sonar-scanner from example project's tools directory installed by the 00-installTools.ps1 script

Let's review the steps to get the TSQL example project scanned. Please note that all the scripts can be replaced with any other means, like a build step on a TFS Build, a plugin in Jenkins, or any other way. The scripts used in this article just illustrate what needs to happen.

Step 1: Setting Up Tools for Scanning

sonar-tsql-plugin supports executing (if the correct path is specified via properties) and reporting issues found by SQLCodeGuard. As we are going to run SQLCover to report coverage, we need that configured as well. Finally, to submit results to SonarQube, we need sonar-scanner or other means to submit reports from the build machine. You can run the script 00-installTools.ps1 from the example project’s directory to download the required files, as depicted below, or do that manually.

Image title

Now we have SQLCode guard, SQLCover, and sonar-scanner on the build machine, which will be required in step 4 so that sonar-scanner can be run. Let's try running sonar-scanner in the example project's directory to see what happens.

$sonarScanner = "./tools/sonar-scanner/sonar-scanner-3.2.0.1227-windows/bin/sonar-scanner.bat";
$sonarArgs = @(
"-Dsonar.projectKey=tsql.sample.project",
"-Dsonar.projectName=TSQL sample project",
"-Dsonar.projectVersion=1.0",
"-Dsonar.sources=src",
"-Dsonar.host.url=http://localhost:9000"
"-Dsonar.exclusions=**/bin/**/*.*,**/obj/**/*.*,**/*.sqlproj"
);
&$sonarScanner $sonarArgs;

TSQL project view in SonarQube before running any tools

We can see a few issues, but we don't have results from the other tools as we haven't run them, including SQLCodeGuard and SQLCover.

Step 2: Sorting Out the Database for tSQLt

In this article, the tSQLt framework is used. In order for the example tests to be run, this framework will be installed onto the database. Again, you can do that manually or run the script 01-executeDBChanges.ps1 to download the tSQLt framework, create ExampleDatabase, and configure it.

Configuring MSSQL database and tSQLt

Now, on MSSQL server, we will publish the ExampleDatabasedatabase with tSQLt installed exits.

Step 3: Publish ExampleDatabase

In order to publish ExampleDatabase, you can just open the ./src/ExampleDatabase/ExampleDatabase.sln solution with Visual Studio from the example project's directory and publish it.

Publish database from Visual Studio

Step 4: Running Analysis Tools and sonar-scanner

After running the previous steps, it is time to actually run the analysis using tools configured above. The steps below were already set up in the 02-runSonar.ps1 script. You can run that script instead by modifying the values as you need. All steps are optional and can be replaced with any other means.

1. SQLCover (Optional)

I used example code found at [1]. This can be replaced by other means, but when running sonar-scanner, you will need to specify the path to the coverage report by setting the sonar.tsql.sqlcover.report property. I will use the script below to run tSQLt and store the results to the ./build/sqlcoverresults folder.

## Run tests with SQLCover
$baseDir = "D:\tsql-example-project"
$database = "ExampleDatabase"
$server = ".\SQLEXPRESS01"
$cloverDir = "$baseDir\tools\SQLCover"
$coverageOutputDir = "$baseDir\build\sqlcoverresults"

. "$cloverDir\SQLCover.ps1" 
$results = Get-CoverTSql  "$cloverDir\SQLCover.dll"  "server=$server;initial catalog=$database;integrated security=sspi;" "$database " "exec tSQLt.RunAll" 
New-Item -ItemType Directory -Force -Path $coverageOutputDir
Export-OpenXml $results "$coverageOutputDir"  


2. Running msbuild Code Analysis (Optional)

This command just builds a database project and runs SQL code analysis against the rules by Microsoft. The Sonar plugin by default will try to find files in the project's folder ending with StaticCodeAnalysis.Results.xml. You can also specify the absolute path to the report using the sonar.tsql.ms.report property.

## Build and run code analysis
$baseDir = "D:\tsql-example-project"
$dbProject = "$baseDir\src\ExampleDatabase\ExampleDatabase.sln"
$msbuildpath = Resolve-Path "C:\Program Files*\MSBuild\*\Bin\*\MSBuild.exe" | select -ExpandProperty Path -First 1
&$msbuildpath "$dbProject" /t:build /p:RunSqlCodeAnalysis=True


3. Running SQLCodeGuard (Optional)

Running SQLCodeGuard before sonar-scanner is optional, as if you specify the sonar.tsql.cg.path to the SQLCodeGuard executable, in my case (D:\tsql-example-project\tools\SQLCodeGuardCmdLine\SqlCodeGuard30.Cmd.exe), the plugin will try to run that. If that's not the intended case, you can run SQLCodeGuard before sonar-scanner and specify the path to the report using the sonar.tsql.cg.report property.

## Run SQLCodeGuard if needed manually
$baseDir = "D:\tsql-example-project"
$sqlCodeGuard = "$baseDir\tools\SQLCodeGuardCmdLine\SqlCodeGuard30.Cmd.exe"
$sqlCodeGuardResults = "$baseDir\build\cgtestresults.xml"
$sqlCodeGuardArgs = @(
"-source",
"$baseDir\src",
"-out",
"$sqlCodeGuardResults",
"/include:all"
)
&$sqlCodeGuard  $sqlCodeGuardArgs

4. Running sonar-scanner

After having run all the previous steps, I will execute sonar-scanner again so that the findings of those tools will be reported to SonarQube.

$baseDir = "D:\tsql-example-project"
$sqlCodeGuard = "$baseDir\tools\SQLCodeGuardCmdLine\SqlCodeGuard30.Cmd.exe"
$sonarScanner = "$baseDir\tools\sonar-scanner\sonar-scanner-3.2.0.1227-windows\bin\sonar-scanner.bat"
$coverageOutputDir = "$baseDir\build\sqlcoverresults"
$sonarArgs = @(
"-Dsonar.projectKey=tsql.sample.project",
"-Dsonar.projectName=TSQL sample project",
"-Dsonar.projectVersion=1.0",
"-Dsonar.sources=src",
"-Dsonar.host.url=http://localhost:9000",
"-Dsonar.projectBaseDir=$baseDir", # skip this if runnning from same directory
"-Dsonar.exclusions=**/bin/**/*.*,**/obj/**/*.*,**/*.sqlproj", # skip build files from analysis

# it is possible to specify absolute path to the SQLCover report or directory where file matching *Coverage.opencoverxml resides, by default plugin will try to find it in the base directory's subdirectories
"-Dsonar.tsql.sqlcover.report=$coverageOutputDir\Coverage.opencoverxml",

# it is possible to either specify path to sqlcodeguard executable and plugin will try to run it or you can specify actual path to report's xml
# or directory where file matching  *cgresults.xml resides by setting sonar.tsql.cg.report property
"-Dsonar.tsql.cg.path=$sqlCodeGuard"
#"-Dsonar.tsql.cg.report=$sqlCodeGuardResults",

# it is possible to specify absolute path to the MSBuild code analysis report or directory where file matching *StaticCodeAnalysis.Results.xml resides, by default plugin will try to find it in the base directory's subdirectories
#"-Dsonar.tsql.ms.report=$baseDir\src\ExampleDatabase\ExampleDatabase\bin\Debug"

);
&$sonarScanner $sonarArgs

After completing this, in SonarQube, you should be able to see he project with the issues found and coverage, and can start fixing the issues.

Image title

Database Build (game engine) operating system

Opinions expressed by DZone contributors are their own.

Related

  • Best Practices for Exchange Server 2019 Storage
  • How to Move System Databases to Different Locations in SQL Server on Linux
  • Using the PostgreSQL Pager With MariaDB Xpand
  • A Beginner's Guide to Back-End Development

Partner Resources

×

Comments

The likes didn't load as expected. Please refresh the page and try again.

  • RSS
  • X
  • Facebook

ABOUT US

  • About DZone
  • Support and feedback
  • Community research

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 215
  • Nashville, TN 37211
  • [email protected]

Let's be friends:

  • RSS
  • X
  • Facebook