In meinem letzten Artikel habe ich grob beschrieben, wie sich Standard SQL von T-SQL unterscheidet und wer was lernen sollte. Jetzt möchte ich mich auf die Unterschiede in der Syntax konzentrieren und diese Unterschiede mit Beispielen illustrieren. Wenn Sie denken, dass T-SQL eine Erweiterung ist, die alle Funktionen von Standard-SQL implementiert, liegen Sie nicht richtig. In SQL Server finden Sie jedoch fast alle Funktionen des SQL-Standards. In diesem Artikel finden Sie Beispiele für einige der Unterschiede in der Syntax zwischen Standard-SQL und Transact-SQL.
#1 Namen von Datenbankobjekten
In relationalen Datenbanksystemen benennen wir Tabellen, Ansichten und Spalten, aber manchmal müssen wir denselben Namen als Schlüsselwort oder mit Sonderzeichen verwenden. In Standard-SQL können Sie diese Art von Namen in Anführungszeichen („“) setzen, in T-SQL können Sie sie aber auch in Klammern () setzen. Sehen Sie sich diese Beispiele für den Namen einer Tabelle in T-SQL an:
CREATE TABLE dbo.test."first name" ( Id INT, Name VARCHAR(100));CREATE TABLE dbo.test. ( Id INT, Name VARCHAR(100));
Nur das erste Begrenzungszeichen (die Anführungszeichen) für den speziellen Namen ist auch Teil des SQL-Standards.
Was ist anders in einer SELECT-Anweisung?
Der SQL-Standard hat keine Syntax für eine Abfrage, die Werte oder Werte aus Ausdrücken zurückgibt, ohne sich auf irgendwelche Spalten einer Tabelle zu beziehen, aber MS SQL Server erlaubt diese Art von Ausdruck. Wie? Sie können eine SELECT-Anweisung allein mit einem Ausdruck oder mit anderen Werten, die nicht aus Spalten der Tabelle stammen, verwenden. In T-SQL sieht das wie im folgenden Beispiel aus:
SELECT 12/6 ;
In diesem Ausdruck brauchen wir keine Tabelle, um 12 geteilt durch 6 auszuwerten, daher können die FROM-Anweisung und der Name der Tabelle weggelassen werden.
#3 Begrenzung der Datensätze in einer Ergebnismenge
Im SQL-Standard können Sie die Anzahl der Datensätze in den Ergebnissen mit der unten dargestellten Syntax begrenzen:
SELECT * FROM tab FETCH FIRST 10 ROWS ONLY
T-SQL implementiert diese Syntax auf eine andere Weise. Das folgende Beispiel zeigt die MS SQL Server-Syntax:
SELECT * FROM tab ORDER BY col1 DESC OFFSET 0 ROWS FETCH FIRST 10 ROWS ONLY;
Wie Sie sehen, wird hier eine ORDER BY-Klausel verwendet. Eine andere Möglichkeit, Zeilen auszuwählen, aber ohne ORDER BY, ist die Verwendung der TOP-Klausel in T-SQL:
SELECT TOP 10 * FROM tab;
#4 Automatically Generating Values
Der SQL-Standard ermöglicht es Ihnen, Spalten mit automatisch generierten Werten zu erstellen. Die Syntax dafür ist unten dargestellt:
CREATE TABLE tab (id DECIMAL GENERATED ALWAYS AS IDENTITY);
In T-SQL können wir auch automatisch Werte generieren, aber auf diese Weise:
CREATE TABLE tab (id INTEGER IDENTITY);
#5 Mathematische Funktionen
Einige allgemeine mathematische Funktionen sind Teil des SQL-Standards. Eine dieser mathematischen Funktionen ist CEIL(x), die wir in T-SQL nicht finden. Stattdessen bietet T-SQL die folgenden Nicht-Standardfunktionen: SIGN(x), ROUND(x,) zum Runden des Dezimalwertes x auf die Anzahl der Nachkommastellen, TRUNC(x) zum Abschneiden auf eine bestimmte Anzahl von Nachkommastellen, LOG(x) zur Rückgabe des natürlichen Logarithmus für einen Wert x und RANDOM() zur Erzeugung von Zufallszahlen. Die höchste oder niedrigste Zahl in einer Liste wird im SQL-Standard mit den Funktionen MAX(list) und MIN(list) zurückgegeben, in Transact-SQL verwendet man jedoch die Funktionen GREATEST(list) und LEAST(list).
T-SQL function ROUND:SELECT ROUND(col) FROM tab;
#6 Aggregate Functions
Einen weiteren Syntaxunterschied finden wir bei den Aggregate Functions. Die Funktionen COUNT, SUM und AVG nehmen alle ein Argument, das sich auf eine Zählung bezieht. T-SQL erlaubt die Verwendung von DISTINCT vor diesen Argumenten, so dass Zeilen nur gezählt werden, wenn sich die Werte von anderen Zeilen unterscheiden. Der SQL-Standard lässt die Verwendung von DISTINCT in diesen Funktionen nicht zu.
Standard SQL:SELECT COUNT(col) FROM tab;T-SQL:SELECT COUNT(col) FROM tab;SELECT COUNT(DISTINCT col) FROM tab;
Aber in T-SQL finden wir keine Populations-Kovarianzfunktion: COVAR_POP(x,y), die im SQL-Standard definiert ist.
#7 Retrieving Parts of Dates and Times
Die meisten relationalen Datenbanksysteme liefern viele Funktionen, um mit Daten und Zeiten zu arbeiten.
In Standard-SQL unterscheiden sich die Funktion EXTRACT(YEAR FROM x) und ähnliche Funktionen zur Auswahl von Teilen von Datumsangaben von den T-SQL-Funktionen wie YEAR(x) oder DATEPART(year, x).
Es gibt auch einen Unterschied bei der Abfrage des aktuellen Datums und der Uhrzeit. Standard-SQL ermöglicht es, das aktuelle Datum mit der Funktion CURRENT_DATE zu ermitteln, aber in MS SQL Server gibt es keine ähnliche Funktion, so dass wir die Funktion GETDATE als Argument in der Funktion CAST verwenden müssen, um in den Datentyp DATE zu konvertieren.
#8 Operieren mit Strings
Die Verwendung von Funktionen zum Operieren mit Strings unterscheidet sich ebenfalls zwischen dem SQL-Standard und T-SQL. Der Hauptunterschied besteht darin, dass nachgestellte und führende Leerzeichen aus einer Zeichenkette entfernt werden. In Standard-SQL gibt es die Funktion TRIM, in T-SQL gibt es mehrere verwandte Funktionen: TRIM (Entfernen von abschließenden und führenden Leerzeichen), LTRIM (Entfernen von führenden Leerzeichen) und RTRIM (Entfernen von abschließenden Leerzeichen).
Eine weitere, sehr häufig verwendete String-Funktion ist SUBSTRING.
Die Standard-SQL-Syntax für die SUBSTRING-Funktion sieht wie folgt aus:
SUBSTRING(str FROM start )
Aber in T-SQL sieht die Syntax dieser Funktion wie folgt aus:
SUBSTRING(str, start, length)
Es gibt manchmal Gründe, Werte aus anderen Spalten und/oder zusätzliche Strings hinzuzufügen. In Standard-SQL gibt es dafür die folgende Syntax:
Wie Sie sehen, verwendet diese Syntax den Operator ||, um eine Zeichenkette zu einer anderen hinzuzufügen.
Der entsprechende Operator in T-SQL ist jedoch das Plus-Zeichen. Sehen Sie sich dieses Beispiel an:
SELECT col1 + col2 FROM tab;
In SQL Server haben wir auch die Möglichkeit, die Funktion CONCAT zu verwenden, die eine Liste von Zeichenfolgen verkettet:
SELECT CONCAT(col1, str1, col2, ...) FROM tab;
Wir können ein Zeichen auch mehrmals wiederholen. Standard-SQL definiert dazu die Funktion REPEAT(str, n). Transact-SQL bietet die Funktion REPLICATE. Zum Beispiel:
SELECT REPLICATE(str, x);
wobei x angibt, wie oft die Zeichenkette oder das Zeichen wiederholt werden soll.
#9 Ungleichheitsoperator
Beim Filtern von Datensätzen in einer SELECT-Anweisung müssen wir manchmal einen Ungleichheitsoperator verwenden. Standard-SQL definiert <> als diesen Operator, während T-SQL sowohl den Standard-Operator als auch den !=-Operator zulässt:
SELECT col3 FROM tab WHERE col1 != col2;
#10 ISNULL-Funktion
In T-SQL haben wir die Möglichkeit, NULL-Werte aus einer Spalte mit der ISNULL-Funktion zu ersetzen. Dies ist eine Funktion, die spezifisch für T-SQL ist und nicht im SQL-Standard enthalten ist.
SELECT ISNULL(col1) FROM tab;
Welche Teile der DML-Syntax sind anders?
In T-SQL ist die grundlegende Syntax von DELETE-, UPDATE- und INSERT-Abfragen dieselbe wie im SQL-Standard, aber bei fortgeschritteneren Abfragen gibt es Unterschiede. Schauen wir uns diese an.
#11 Schlüsselwort OUTPUT
Das Schlüsselwort OUTPUT kommt in DELETE-, UPDATE- und INSERT-Anweisungen vor. Es ist in Standard-SQL nicht definiert.
Mit T-SQL können wir zusätzliche Informationen sehen, die von einer Abfrage zurückgegeben werden. Bei UPDATE werden sowohl alte als auch neue Werte zurückgegeben, bei INSERT die hinzugefügten oder bei DELETE die gelöschten Werte. Um diese Informationen zu sehen, müssen wir Präfixe in INSERT, UPDATE und DELETE verwenden.
UPDATE tab SET col='new value' OUTPUT Deleted.col, Inserted.col;
Wir sehen das Ergebnis der Änderung von Datensätzen mit den vorherigen und neuen Werten in einer aktualisierten Spalte. Der SQL-Standard unterstützt diese Funktion nicht.
#12 Syntax für INSERT INTO … SELECT
Eine weitere Struktur einer INSERT-Abfrage ist INSERT INTO … SELECT. Mit T-SQL können Sie Daten aus einer anderen Tabelle in eine Zieltabelle einfügen. Sehen Sie sich diese Abfrage an:
INSERT INTO tab SELECT col1,col2,... FROM tab_source;
Es handelt sich nicht um eine Standardfunktion, sondern um eine für SQL Server charakteristische Funktion.
#13 FROM-Klausel in DELETE und UPDATE
SQL Server bietet eine erweiterte Syntax der UPDATE- und DELETE mit FROM-Klauseln. Sie können DELETE mit FROM verwenden, um die Zeilen aus einer Tabelle zu verwenden, um die entsprechenden Zeilen in einer anderen Tabelle zu entfernen, indem Sie sich auf einen Primärschlüssel und einen Fremdschlüssel beziehen. Ebenso können Sie mit UPDATE with FROM Zeilen aus einer Tabelle aktualisieren, indem Sie auf die Zeilen einer anderen Tabelle verweisen, die gemeinsame Werte verwenden (Primärschlüssel in einer Tabelle und Fremdschlüssel in der zweiten, z. B. derselbe Ortsname). Hier ein Beispiel:
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;
Der SQL-Standard sieht diese Syntax nicht vor.
#14 INSERT, UPDATE und DELETE mit JOIN
Sie können auch INSERT, UPDATE und DELETE mit JOIN verwenden, um eine Verbindung zu einer anderen Tabelle herzustellen. Ein Beispiel dafür ist:
DELETE ItemOrder FROM ItemOrderJOIN Item ON ItemOrder.ItemId=Item.IdWHERE YEAR(Item.DeliveredDate) <= 2017;
Diese Funktion ist nicht im SQL-Standard enthalten.
Zusammenfassung
Dieser Artikel behandelt nicht alle Fragen zu den Syntaxunterschieden zwischen dem SQL-Standard und T-SQL unter Verwendung des MS SQL Server-Systems. Dieser Leitfaden hilft jedoch dabei, einige grundlegende Merkmale aufzuzeigen, die nur für Transact-SQL charakteristisch sind und welche Syntax des SQL-Standards nicht von MS SQL Server implementiert wird.