Farbschema: Dunkel
Sie befinden sich hier: start » de » Dokumentation » Datenintegration und Datenzugriff » WKL OData-ODBC-Treiber » Referenz des OData-ODBC-Treibers » Unterstütztes SQL (Referenz)

Unterstütztes SQL (Referenz)

Diese Referenz zeigt, welche SQL-Anweisungen der Treiber in OData-Anfragen übersetzt, wie er sie übersetzt und was er abweist. Sie brauchen diese Seite, wenn eine Abfrage aus Access, ADO.NET oder VBA nicht wie erwartet läuft oder wenn Sie eine Abfrage so schreiben wollen, dass sie ohne eigene Anweisungen auskommt. Den Überblick gibt das Konzept Wie der Treiber Anweisungen übersetzt. Welche Mengen und Spalten es überhaupt gibt und woher ihre Typen kommen, steht vorher unter Wie aus einem OData-Dienst ein relationales ODBC-Modell wird.

Syntax

SELECT <Spalten | Aggregate> FROM <Menge> [WHERE <Bedingung>] [GROUP BY <Spalten> [HAVING <Bedingung>]]
  [ORDER BY <Spalten> [OFFSET n ROWS [FETCH NEXT m ROWS ONLY]]]
INSERT INTO <Menge> (…) VALUES (…)
UPDATE <Menge> SET … WHERE <Schlüssel> = ? [AND <Zeilenversion> = ?]
DELETE FROM <Menge> WHERE <Schlüssel> = ? [AND <Zeilenversion> = ?]

Eine übersetzte Anweisung liest genau eine Entitätsmenge. Alles andere geht an die Adresse für eigene Anweisungen oder wird abgewiesen.

Parameter

Bedingungen

SQLOData
=, <>, <, <=, >, >=, IS NULL, IS NOT NULLeq, ne, lt, le, gt, ge, eq null, ne null
Spalte gegen Spalte derselben Tabelle (C.ParentId = C.Id), auch unter einem Tabellennamen-AliasParentId eq Id; Spalten verschiedener Typfamilien (Zahl gegen Text) weist der Treiber ab. Braucht einen Dienst, der Feld gegen Feld annimmt
AND, OR, NOT, Klammernand, or, not, Klammern
IN (…), NOT IN (…)Oder-Kette, verneint
LIKE 'x%', '%x', '%x%'startswith, endswith, contains
LIKE mit einem Zeichen in eckigen Klammern ('B[_]%')das Zeichen selbst, wie in SQL Server
Parameter ?gebundener Wert, als Literal in den Filter

Gruppieren und Zusammenfassen

Access schickt Summen und Gruppen über eine verknüpfte Tabelle an den Treiber, gleich was SQLGetInfo über ihn sagt, und rechnet sie nicht selbst, wenn der Treiber ablehnt – die Abfrage scheitert dann mit „ODBC-Aufruf fehlgeschlagen“ (auch mit SQL_ODBC_SQL_CONFORMANCE = 0). Mit einer Adresse für eigene Anweisungen gehen sie unverändert an die Datenbank. Ohne sie übersetzt der Treiber sie nach $apply (OData Data Aggregation 4.0) – aber nur, wenn das Schemadokument Org.OData.Aggregation.V1.ApplySupported mit den nötigen Transformationen ankündigt. Ein Dienst ohne diese Ankündigung beantwortete $apply bestenfalls mit einem Fehler, schlimmstenfalls – wenn er Unbekanntes übergeht – mit den Zeilen ohne Gruppierung, die die Anwendung für die Gruppen hielte.

Access schickt AVG nicht, sondern SUM und COUNT(x) und teilt selbst; für StDev und Var zusätzlich SUM(x * x); TOP n behält es; ORDER BY nennt die Spalte voll qualifiziert ("dbo"."Artikel"."Gruppe"), auch innerhalb eines Aggregats; eine Gruppierung nach Year(…) rechnet es selbst über die gelesene Spalte.

Access schicktDer Treiber fragt
SELECT SUM("x") FROM "dbo"."t" "R"t?$apply=aggregate(x with sum as gw_a1)
SELECT "g", COUNT(*) FROM … WHERE ("id" > 3) GROUP BY "g" ORDER BY "dbo"."t"."g" DESC$apply=filter(id gt 3)/groupby((g),aggregate($count as gw_a1))&$orderby=g desc
… GROUP BY "g" HAVING (COUNT(*) > 1)$filter=gw_a1 gt 1 auf die Gruppen
… HAVING SUM("b") >= ? (Aggregat nicht ausgewählt)angefragt als gw_a1, verglichen, aber nicht als Spalte gezeigt
… ORDER BY SUM("dbo"."t"."id") DESCdasselbe Aggregat wie in der Auswahl, $orderby=gw_a1 desc
SELECT DISTINCT "g" FROM …groupby((g))
SELECT COUNT("x"), SUM(("x" * "x")), SUM("x") FROM …compute((x mul x) as gw_c1)/aggregate(x with Wkl.Store.V1.count as gw_a1,gw_c1 with sum as gw_a2,x with sum as gw_a3)
SELECT COUNT(*) FROM … alleinweiter $count – das beantwortet jeder Dienst

COUNT(x) – die Werte, die nicht fehlen – kennt das Protokoll nicht als Standardmethode; der Treiber nutzt dafür Wkl.Store.V1.count, wenn der Dienst sie mit Aggregation.CustomAggregationMethods ankündigt, und lehnt sonst ab. Die Aliasse gw_aN und gw_cN wählt er so, dass keine Eigenschaft der Menge so heißt.

Spaltentypen wie bei Microsofts Treiber für SQL Server, damit Access dieselben Felder anlegt: eine Anzahl ist int, die Summe ganzer Zahlen bis int ist int (ein größerer Wert scheitert, wie dort am Überlauf), die von bigint ist bigint, die einer Dezimalzahl decimal(38, s); MIN und MAX haben den Typ der Spalte. Eine Abweichung mit Absicht: Der Mittelwert ganzer Zahlen ist float mit Nachkommastellen, wo SQL Server eine ganze Zahl liefert – der Dienst rechnet den wahren Mittelwert, und ihn als ganze Zahl zu beschreiben schnitte ab, was er schickt. Eine Spalte heißt wie ihr Alias in der Anweisung; ohne Alias hat sie keinen Namen, wie beim ODBC Driver 18 (Access nennt sie dann selbst Expr1000, Expr1001 …).

Abgewiesen mit 42000 statt angenähert: Rechnen zwischen Aggregaten (SUM(a) - SUM(b)), Division, andere Funktionen als SUM, MIN, MAX, AVG, COUNT, eine Spalte in der Auswahl, die nicht gruppiert ist, DISTINCT in SUM oder AVG, ein Parameter innerhalb eines Aggregats, * neben GROUP BY. Mit einer Adresse für eigene Anweisungen geht auch das an die Datenbank.

Werte und Feldtypen einer übersetzten Summenabfrage sind in Access dieselben wie über Microsofts ODBC Driver 18. Läuft eine Summe über int über, scheitert sie wie dort.

Seitenweise lesen mit OFFSET/FETCH

Eine Anwendung, die ein großes Ergebnis Bildschirm für Bildschirm zeigt, fragt jede Seite mit der Blätterform von SQL Server und des SQL-Standards an. Der Treiber übersetzt sie ohne Adresse für eigene Anweisungen: OFFSET n wird $skip=n, FETCH NEXT m ROWS ONLY wird $top=m; Bedingung und Sortierung gehen wie sonst als $filter und $orderby mit. Beispiel, wie ein Datengitter es über eine eigene Verbindung mit SQLExecDirect schickt:

SELECT S."ID", S."Kunde", S."Umsatz" FROM "dbo"."Umsatz" S
ORDER BY S."Umsatz" DESC, S."ID" OFFSET 500000 ROWS FETCH NEXT 200 ROWS ONLY

wird zu Umsatz?$select=ID,Kunde,Umsatz&$orderby=Umsatz desc,ID&$skip=500000&$top=200.

RegelGrund
OFFSET nur hinter ORDER BY; ROW/ROWS, FIRST/NEXT gleichwertig; FETCH darf fehlenWie in SQL Server: ohne Ordnung gibt es keine feste Position
Werte als ganze Zahl oder Parameter (?); OFFSET ab 0, FETCH ab 1Was SQL Server abweist (Fehler 10742, 10744), weist auch der Treiber ab
TOP neben OFFSET wird abgewiesenSQL Server weist eine solche Anweisung ebenfalls ab (Fehler 10741)
Gruppierte Anweisungen (GROUP BY, DISTINCT) blättern genausoDer Dienst blättert die Gruppen nach $apply mit $skip/$top
SQL_ATTR_MAX_ROWS begrenzt FETCH zusätzlichWie bei TOP
COUNT(*) mit Bedingung – auch die Rangbedingung für die Position eines Satzes – bleibt $count; COUNT(*) AS name behält den NamenDie Spalte hat sonst keinen Namen, und ein Leser nach Namen fände sie nicht

Die Wörter OFFSET, FETCH, ROWS, NEXT usw. erkennt der Treiber nur am Ende von ORDER BY; eine Spalte namens Next bleibt unverändert schreibbar.

Wie teuer eine tiefe Seite ist, entscheidet der Dienst mit seiner Datenbank, nicht der Treiber. Der Datendienst Wkl.Data.Gateway macht aus $skip ein OFFSET … ROWS, und SQL Server liest dafür alle Zeilen davor. Eine flache Seite kostet über den Treiber zusätzlich den festen Aufschlag einer HTTP-Anfrage.

Rückgabewert

Spaltennamen sind der Alias der Anweisung; ohne Alias ist der Name leer, wie beim ODBC Driver 18. Spaltentypen folgen den Regeln unter „Gruppieren und Zusammenfassen“.

Bemerkungen

  • LIKE geht nur in den Formen x%, %x, %x% und ohne _ als Platzhalter. Ein einzelnes Zeichen in eckigen Klammern ([_], [%]) oder hinter einem Fluchtzeichen (ESCAPE) gilt als dieses Zeichen und ist erlaubt. Eine Zeichenklasse wie [a-c] oder [^a] hat in OData keine Entsprechung.
  • Ausdrücke in der Feldliste übersetzt der Treiber nur innerhalb eines Aggregats.
  • Verknüpfungen und Unterabfragen kündigt SQLGetInfo nicht an; Access schickt Verbünde dennoch, und sie laufen nur über die Adresse für eigene Anweisungen.
  • Der Cursor liest vorwärts, ohne Lesezeichen und ohne Sperren.
  • GUID-Werte (uniqueidentifier, Edm.Guid): als Literal in der Schreibweise von Access ({guid {33333333-…}}), als Text oder als Parameter vom Typ Guid bzw. als 16 Byte; an den Dienst geht die Form von OData v4 ohne Typnamen. Für ODBC-2-Anwendungen wie Access liefert der Treiber eine GUID ohne angefragten Typ als Text, wie ODBC Driver 18. Das gilt in Access für Datenblatt, Formular, Unterformular und Nachschlageliste.

Beispiel

Access:  SELECT ... FROM Artikel WHERE Gruppe = 'S' ORDER BY Nummer
Dienst:  GET .../Artikel?$filter=Gruppe eq 'S'&$orderby=Nummer&$select=...

Gilt für

Treiber Wkl OData, beide Bitbreiten; Gruppieren nur gegen einen Dienst, der $apply ankündigt (siehe Anforderungen an einen OData-Dienst).

Ausnahmen

SQLSTATEBedingung
42000Die Anweisung lässt sich nicht übersetzen und es gibt keine Adresse für eigene Anweisungen; die Meldung nennt den Grund, etwa die Spalte oder das Konstrukt

Siehe auch

de/wiki/data-conectivity/odata-odbc/reference/supported-sql.txt · Zuletzt geändert: von Wolfgang van der Stille