Write a script to run on different SQL engines - sql-server

I'm writing a SQL script that needs to be able to run on multiple SQL engines, namely SQL Server and Azure SQL. An IF statement checks the database version to execute the correct code. But the code won't compile if used on the wrong engine.
This works fine in Azure SQL, but SQL Server rejects it.
IF (##VERSION LIKE 'Microsoft SQL Azure %')
BEGIN
ADD SENSITIVITY CLASSIFICATION TO [dbo].[User].[UserName] WITH (LABEL = 'Confidential', INFORMATION_TYPE = 'Credentials')
...
END
GO
What are my options for ensuring this is accepted by both engines?

Dynamic SQL could be used to circumvent syntax check:
IF (##VERSION LIKE 'Microsoft SQL Azure %')
BEGIN
EXEC('ADD SENSITIVITY CLASSIFICATION TO [dbo].[User].[UserName] WITH (LABEL = ''Confidential'', INFORMATION_TYPE = ''Credentials'')');
...
END
GO
Please note that all ' have to be quoted i.e.''. Add support for here-strings i T-SQL
ADD SENSITIVITY CLASSIFICATION will be supported starting from SQL Server 2019.

Related

How do I test whether a given SQL Syntax is valid for an older version of SQL Server

I regularly end up developing on projects where either the Central Test server, or Prod server is an older version of SQL Server than my local install.
e.g. Prod is SQL Server 2014. Local install in SQL Server 2019.
Mostly that's fine, it just means I have to remember to only use old syntaxes. (:cry:)
But occasionally I forget which syntaxes are old. Ooops.
Obviously our test environments catch this, but it would be great to be able to tell my Local Server ... "only accept SS2014 syntax", and have these mistakes caught before they're committed/pushed.
I thought this was what CompatibilityLevel was supposed to do. But either it doesn't, or I'm using it wrong. (See below)
How should I achieve this? (other than just installing a different SQL version!)
Attempt so far:
Run ALTER DATABASE MyLocalProjectDB SET COMPATIBILITY_LEVEL = 120; (120 represents SS2014)
Run SELECT name, compatibility_level FROM sys.databases WHERE name = db_name(); to confirm that the previous command "worked".
Run DROP TABLE IF EXISTS [ATableThatDoesExist], to see if the syntax is accepted. It was.
DROP IF EXISTS was new to SS2016:
MSDN: IF EXISTS ... Applies to: SQL Server ( SQL Server 2016 (13.x) through current version).
Additional Source
Why hasn't this worked?

VB.net parameterized query uses sp_executesql but loses UTF8 characters

I have an odd scenario that I'm looking for some clarification on.
I currently have an VB.net application that is sending the parameterized query below to an SQL Server 2019 database using ADO.net. To make the database support UTF8, we are using one of the new _UTF8 collations. For this test, we are using a database configured to use Latin1_General_100_CI_AI_SC_UTF8.
Query:
exec sp_executesql
N'UPDATE Roles SET Name = #pName WHERE Role_ID = 6',
N'#pName varchar(1000)',
#pName='æææDeveloper'
Now, I know that when I run the query above in MSSQL Management Studio, I don't lose my 'æ' characters but if I run this through code, my characters are replaced by '?'. My question is why would I lose them through code via ADO.net and not through MSSQL Management Studio.
I also know that sp_executesql does not support varchar as parameters which was the main problem and we were able to solve but again. Why would it work in MSSQL but not in ADO.net?

SQL Server Profiler does not show data in SQL statement

I am using the SQL Server Profiler to trace the SQL generated from nHibernate in a Windows SmartClient appplication.
The trace of the SQL statement does not show actual data, but rather, looks like this:
exec sp_executesql N'SELECT attachment0_.RecordKey as RecordKey1_, attachment0_.Id as Id1_, attachment0_.Id as Id87_0_, attachment0_.RecordType as RecordType87_0_, attachment0_.RecordKey as RecordKey87_0_, attachment0_.FileName as FileName87_0_, attachment0_.OriginalFileName as Original6_87_0_, attachment0_.DateTimeAttached as DateTime7_87_0_ FROM MyDatabase.dbo.tblAttachment attachment0_ WHERE attachment0_.RecordKey=#p0',N'#p0 int',#p0=262
Is there a way to see the the actual data in the SQL command?
It's just showing the parameterized sql. If you want to log or to show non-parameterized sql I came up with a solution to this here:
Execute NHibernate-generated prepared statements in SQL Server Management Studio
The item of note is the log4net appender that basically translates this in the accepted answer.

Does SQL Azure support REPLACE T-SQL function with cyrillic characters?

I am trying command like
USE [aaa]
GO
SELECT [Id]
,REPLACE([BlaBlaField], 'xyz','')
FROM [dbo].[aaa]
GO
through SQL Management Studio on SQL EXPRESS and SQL Azure Web Edition DB. In SQL Express it works, but on Azure it does not. I searched on the web at 'Azure SQL Database General Guidelines and Limitations' page and on this page but the command was not listed as not supported. Is it supported or not?
UPDATE
The problem appears only when I use cyrillic symbols. For example :
USE [aaa]
GO
SELECT [Id]
,REPLACE([BlaBlaField], '2004','-')
FROM [dbo].[aaa]
GO
works but :
USE [aaa]
GO
SELECT [Id]
,REPLACE([BlaBlaField], '2004г','')
FROM [dbo].[aaa]
GO
UPDATE - PROBLEM SOLVED
The problem was solved by not using REPLACE but a combination of LEFT, RIGHT, SUBSTRING and CHARINDEX avoiding the use or cyrillic characters.
does not.
The replace function itself works in Azure SQL Database.
What does not work in SQL Database is USE [aaa]. You have to connect to the correct database first and then issues the statement in.

SQL Server trigger to determine crud source

I have a web application and the database it is on my client building. I want to know if the CRUD (create, update, delete) actions made from my application of "someone" for any reason, done it from SQL Server Management Studio.
Thanks in advance
You could define a trigger for update/insert on the tables you want to audit, then adapt the following code from this MSDN article on AppName() :
DECLARE #CurrentApp varchar(40)
SET #CurrentApp = APP_NAME()
IF #CurrentApp <> 'SQL Server Management Studio - Query'
PRINT 'This process was not started by a SQL Server Management Studio query session.';
I believe it might be open to spoofing though, as I think programs can specify the application name in the connection string.

Resources