In mijn laatste artikel heb ik globaal beschreven hoe standaard SQL verschilt van T-SQL en wie welke zou moeten leren. Nu wil ik me concentreren op de syntax verschillen en deze verschillen illustreren met voorbeelden. Als u denkt dat T-SQL een uitbreiding is die alle functies uit standaard SQL implementeert, dan heeft u het niet bij het rechte eind. Echter, in SQL Server vindt u bijna alle functies van de SQL standaard. In dit artikel vindt u voorbeelden van enkele verschillen in syntaxis tussen standaard SQL en Transact-SQL.
#1 Namen van Database Objecten
In relationele databasesystemen geven we tabellen, views en kolommen een naam, maar soms moeten we dezelfde naam als een trefwoord gebruiken of speciale tekens gebruiken. In standaard SQL kunt u dit soort namen tussen aanhalingstekens (“”) plaatsen, maar in T-SQL kunt u ze ook tussen haakjes () plaatsen. Kijk naar deze voorbeelden voor de naam van een tabel in T-SQL:
CREATE TABLE dbo.test."first name" ( Id INT, Name VARCHAR(100));CREATE TABLE dbo.test. ( Id INT, Name VARCHAR(100));
Alleen het eerste scheidingsteken (de aanhalingstekens) voor de speciale naam maakt ook deel uit van de SQL standaard.
Wat is anders in een SELECT Statement?
De SQL standaard heeft geen syntax voor een query die waarden retourneert of waarden die afkomstig zijn van expressies zonder te verwijzen naar kolommen van een tabel, maar MS SQL Server staat dit type expressie wel toe. Hoe? Je kunt een SELECT statement alleen gebruiken met een expressie of met andere waarden die niet uit kolommen van de tabel komen. In T-SQL ziet het er uit als in onderstaand voorbeeld:
SELECT 12/6 ;
In deze expressie hebben we geen tabel nodig om 12 gedeeld door 6 te evalueren, daarom kunnen het FROM statement en de naam van de tabel weggelaten worden.
#3 Records in een resultatenset beperken
In de SQL-standaard kunt u het aantal records in de resultaten beperken met behulp van de syntaxis die hieronder wordt geïllustreerd:
SELECT * FROM tab FETCH FIRST 10 ROWS ONLY
T-SQL implementeert deze syntaxis op een andere manier. Het voorbeeld hieronder toont de MS SQL Server syntaxis:
SELECT * FROM tab ORDER BY col1 DESC OFFSET 0 ROWS FETCH FIRST 10 ROWS ONLY;
Zoals u ziet, gebruikt dit een ORDER BY clausule. Een andere manier om rijen te selecteren, maar zonder ORDER BY, is door gebruik te maken van de TOP-clausule in T-SQL:
SELECT TOP 10 * FROM tab;
#4 Automatisch genereren van waarden
De SQL-standaard stelt u in staat om kolommen te maken met automatisch gegenereerde waarden. De syntaxis om dit te doen ziet u hieronder:
CREATE TABLE tab (id DECIMAL GENERATED ALWAYS AS IDENTITY);
In T-SQL kunnen we ook automatisch waarden genereren, maar dan op deze manier:
CREATE TABLE tab (id INTEGER IDENTITY);
#5 Math Functions
Een aantal veelgebruikte mathematische functies maakt deel uit van de SQL-standaard. Een van deze wiskundige functies is CEIL(x), die we niet in T-SQL aantreffen. In plaats daarvan biedt T-SQL de volgende niet-standaard functies: SIGN(x), ROUND(x,) om decimale waarde x af te ronden op het aantal decimale posities, TRUNC(x) om te trunceren tot een gegeven aantal decimalen, LOG(x) om de natuurlijke logaritme voor een waarde x terug te geven, en RANDOM() om willekeurige getallen te genereren. Het hoogste of laagste getal in een lijst in de SQL standaard wordt geretourneerd door MAX(lijst) en MIN(lijst) functies, maar in Transact-SQL gebruikt u de GREATEST(lijst) en LEAST(lijst) functies.
T-SQL function ROUND:SELECT ROUND(col) FROM tab;
#6 Aggregate Functies
We vinden nog een syntax verschil met de aggregate functies. De functies COUNT, SUM, en AVG nemen allemaal een argument dat gerelateerd is aan een telling. T-SQL staat het gebruik van DISTINCT voor deze argumentwaarden toe, zodat rijen alleen worden geteld als de waarden verschillen van andere rijen. De SQL standaard staat het gebruik van DISTINCT in deze functies niet toe.
Standard SQL:SELECT COUNT(col) FROM tab;T-SQL:SELECT COUNT(col) FROM tab;SELECT COUNT(DISTINCT col) FROM tab;
Maar in T-SQL vinden we geen populatie covariantie functie: COVAR_POP(x,y), die wel in de SQL-standaard is gedefinieerd.
#7 Ophalen van delen van data en tijden
De meeste relationele databasesystemen leveren veel functies om data en tijden te bewerken.
In standaard SQL zijn de functie EXTRACT(YEAR FROM x) en soortgelijke functies om delen van datums te selecteren anders dan de T-SQL functies zoals YEAR(x) of DATEPART(year, x).
Er is ook een verschil in het verkrijgen van de huidige datum en tijd. Met standaard SQL kunt u de huidige datum opvragen met de functie CURRENT_DATE, maar in MS SQL Server is er geen vergelijkbare functie, zodat we de functie GETDATE moeten gebruiken als argument in de CAST-functie om te converteren naar een datatype DATE.
#8 Werken met tekenreeksen
Het gebruik van functies om met tekenreeksen te werken is ook verschillend tussen de SQL-standaard en T-SQL. Het belangrijkste verschil zit hem in het verwijderen van spaties voor en achter een string. In standaard SQL is er de TRIM-functie, maar in T-SQL zijn er verschillende verwante functies: TRIM (verwijderen van voorloop- en volgspaties), LTRIM (verwijderen van voorloopspaties), en RTRIM (verwijderen van volgspaties).
Een andere zeer vaak gebruikte string-functie is SUBSTRING.
De standaard SQL-syntaxis voor de SUBSTRING-functie ziet er als volgt uit:
SUBSTRING(str FROM start )
Maar in T-SQL ziet de syntaxis van deze functie er als volgt uit:
SUBSTRING(str, start, length)
Er zijn soms redenen om waarden toe te voegen die afkomstig zijn uit andere kolommen en/of extra strings. Standaard SQL biedt de volgende syntaxis om dit te doen:
Zoals u kunt zien, maakt deze syntaxis gebruik van de || operator om de ene string aan de andere toe te voegen.
Maar de equivalente operator in T-SQL is het plusteken karakter. Kijk eens naar dit voorbeeld:
SELECT col1 + col2 FROM tab;
In SQL Server hebben we ook de mogelijkheid om de CONCAT functie te gebruiken om een lijst van strings samen te voegen:
SELECT CONCAT(col1, str1, col2, ...) FROM tab;
We kunnen een karakter ook meerdere keren herhalen. Standaard SQL definieert de functie REPEAT(str, n) om dit te doen. Transact-SQL biedt de functie REPLICATE. Bijvoorbeeld:
SELECT REPLICATE(str, x);
waarbij x aangeeft hoe vaak de string of het karakter moet worden herhaald.
#9 Inequality Operator
Tijdens het filteren van records in een SELECT statement, moeten we soms een inequality operator gebruiken. Standaard SQL definieert <> als deze operator, terwijl T-SQL zowel de standaard operator als de != operator toestaat:
SELECT col3 FROM tab WHERE col1 != col2;
#10 ISNULL Functie
In T-SQL hebben we de mogelijkheid om NULL waarden die uit een kolom komen te vervangen met behulp van de ISNULL functie. Dit is een functie die specifiek is voor T-SQL en die niet in de SQL-standaard staat.
SELECT ISNULL(col1) FROM tab;
Welke delen van de DML Syntax zijn anders?
In T-SQL is de basis syntax van DELETE, UPDATE, en INSERT queries hetzelfde als in de SQL standaard, maar in meer geavanceerde queries komen verschillen voor. Laten we ze eens bekijken.
#11 OUTPUT Keyword
Het OUTPUT keyword komt voor in DELETE, UPDATE, en INSERT statements. Het is niet gedefinieerd in standaard SQL.
Met T-SQL kunnen we extra informatie zien die door een query wordt geretourneerd. Het geeft zowel oude en nieuwe waarden in UPDATE of de waarden toegevoegd met INSERT of verwijderd met DELETE. Om deze informatie te zien, moeten we voorvoegsels gebruiken in INSERT, UPDATE, en DELETE.
UPDATE tab SET col='new value' OUTPUT Deleted.col, Inserted.col;
We zien het resultaat van het wijzigen van records met de vorige en de nieuwe waarden in een bijgewerkte kolom. De SQL-standaard ondersteunt deze functie niet.
#12 Syntaxis voor INSERT INTO … SELECT
Een andere structuur van een INSERT query is INSERT INTO … SELECT. Met T-SQL kun je gegevens uit een andere tabel invoegen in een bestemmingstabel. Kijk eens naar deze query:
INSERT INTO tab SELECT col1,col2,... FROM tab_source;
Het is geen standaardfunctie, maar een kenmerk van SQL Server.
#13 FROM-clausule in DELETE en UPDATE
SQL Server biedt uitgebreide syntaxis van de UPDATE en DELETE met FROM-clausules. U kunt DELETE with FROM gebruiken om de rijen van een tabel te gebruiken om corresponderende rijen in een andere tabel te verwijderen door te verwijzen naar een primaire sleutel en een vreemde sleutel. Op dezelfde manier kun je UPDATE with FROM gebruiken om rijen uit een tabel bij te werken door te verwijzen naar de rijen van een andere tabel met gemeenschappelijke waarden (primary key in de ene tabel en foreign key in de tweede, bijv. dezelfde plaatsnaam). Hier is een voorbeeld:
DELETE FROM BookFROM AuthorWHERE Author.Id=Book.AuthorId AND Author.Name IS NULL;
UPDATE BookSET Book.Price=Book.Price*0.2FROM AuthorWHERE Book.AuthorId=Author.Id AND Author.Id=12;
De SQL-standaard voorziet niet in deze syntaxis.
#14 INSERT, UPDATE, en DELETE met JOIN
U kunt INSERT, UPDATE, en DELETE ook gebruiken met JOIN om verbinding te maken met een andere tabel. Een voorbeeld hiervan is:
DELETE ItemOrder FROM ItemOrderJOIN Item ON ItemOrder.ItemId=Item.IdWHERE YEAR(Item.DeliveredDate) <= 2017;
Deze functie staat niet in de SQL-standaard.
Samenvatting
Dit artikel behandelt niet alle kwesties over syntaxisverschillen tussen de SQL-standaard en T-SQL met behulp van het MS SQL Server-systeem. Deze gids helpt u echter wel te wijzen op een aantal basisfuncties die alleen kenmerkend zijn voor Transact-SQL en welke SQL-standaard syntaxis niet wordt geïmplementeerd door MS SQL Server.