Grenzen und bekannte Einschränkungen (Referenz)
Was der OData-ODBC-Treiber nicht kann oder anders tut als der ODBC-Treiber von SQL Server, und warum. Jede Grenze nennt, wo die Abhilfe beschrieben ist.
Grenzen
- Nur OData v4 mit JSON. OData v2/v3 und Dienste ohne
$metadatawerden nicht unterstützt. - Bitbreite: Eine 32-Bit-Anwendung lädt nur den x86-Treiber, eine 64-Bit-Anwendung nur den x64-Treiber. Das Installationspaket installiert beide; es setzt 64-Bit-Windows voraus.
- Transaktionen nur, wo der Dienst sie anbietet. Kündigt der Dienst in
$metadataeine Adresse für Transaktionen an (Store.Transactions, so etwa der Datendienst Wkl.Data.Gateway), wirkenBeginTrans,CommitTransundRollbackin VBA/DAO undBeginTransactionin ADO.NET wie über den Treiber von SQL Server. Ohne diese Ankündigung meldet der Treiber keine Transaktionen: ADO.NET erhält beiBeginTransactionden FehlerHYC00, und Access behältBeginTransdann für sich – einRollbacknimmt auf dem Dienst nichts zurück. Bricht die Verbindung währendCommitTransab, ist unbekannt, ob gespeichert wurde. Wie Sie das vor dem Einsatz prüfen und was bei Fehlern geschieht, steht unter Transaktionen. - Auf einen ausgelasteten Dienst wartet der Treiber. Antwortet der Dienst beim Lesen mit
429(zu viele Anfragen) oder503(vorübergehend nicht verfügbar), wartet der Treiber so lange, wieRetry-Aftersagt, und fragt erneut; ohne Angabe wartet er 1, 2, 4, 8 und 16 Sekunden. Eine einzelne Wartezeit über 60 Sekunden oder mehr als 120 Sekunden insgesamt wartet er nicht ab, sondern meldetHYT00mit der Zeit des Dienstes. Den Dialog Verbinden öffnet ein ausgelasteter Dienst nicht.RETRY=OFFschaltet auch das Warten ab. - Wiederholung nach einem Verbindungsabbruch ist eingeschaltet. Der Treiber wiederholt Lesen und Schreiben nach 1 und 3 Sekunden; beim Schreiben ist das nur sicher, wenn der Dienst
Idempotency-Keyeinhält. Für einen Dienst, der das nicht tut, schalten Sie sie mitRETRY=OFFab. Siehe Zusagen je Art des Dienstes. - Der
CommandBuildervon ADO.NET in der Vorgabe braucht die Durchreiche, oder eine andere Nebenläufigkeitsregel; siehe ADO.NET und Visual Studio. - ADO.NET überträgt einen
DateTimenur auf die Millisekunde; siehe ADO.NET und Visual Studio. - Nur, was sich übersetzen lässt – oder durchgereicht wird. Eine Anweisung, die nicht in eine OData-Abfrage passt, wird abgewiesen, sofern die Verbindung keine Adresse für eigene Anweisungen nennt (siehe Wie der Treiber Anweisungen übersetzt). Der Treiber lädt in keinem Fall stillschweigend die ganze Entitätsmenge, um lokal zu filtern.
- Bearbeiten ohne Schlüssel nur, wenn der Dienst es anbietet. Eine Entitätsmenge ohne Schlüssel ist schreibgeschützt, es sei denn,
$metadatadeklariert für sie die AktionenUpdateByOriginalundDeleteByOriginal. Dann nennt Access den Satz über seine alten Werte; gleiche Sätze bleiben unveränderbar. - Ändern und Löschen brauchen eine Zeilenversion, die der Dienst deklariert. Deklariert er eine – eine gespeicherte Spalte oder einen berechneten Wert –, nimmt Access sie als einzige Zusatzbedingung, und der Treiber macht daraus
If-Match; ein Schreibkonflikt erscheint dann in Access als solcher. Deklariert er keine, stellt Access die alten Werte aller Spalten in die Bedingung. Das lässt sich in OData nicht ausdrücken, und der Treiber weist es ab, statt die Prüfung stillschweigend fallen zu lassen: Sonst überschriebe die Änderung eine fremde Änderung, die Access für ausgeschlossen hält. Anlegen ist auch ohne Zeilenversion möglich. Abhilfe schafft der Dienst, nicht der Treiber: Er deklariert eine Zeilenversion oder einen berechneten Stempel. - Eine übersetzte Anweisung liest genau eine Entitätsmenge; Verbünde und Unterabfragen laufen nur über die Durchreiche, siehe Unterstütztes SQL.
LIKEnur in den Formenx%,%x,%x%und ohne_als Platzhalter ([_]und ein Fluchtzeichen sind erlaubt); siehe Unterstütztes SQL.- Der Cursor liest vorwärts, ohne Lesezeichen und ohne Sperren.
- Ein paar Zeichen bleiben im Namen kodiert (
!,",.,[,],`, Steuerzeichen, Leerzeichen am Anfang); siehe Fehlerbehebung. - Ein Name mit mehr als 64 Zeichen scheitert in Access, wie über den Treiber von SQL Server; siehe Fehlerbehebung.
- Access teilt Verbindungen nach
DATABASE. Zwei Verknüpfungen mit gleichemDATABASElaufen über eine Verbindung, auch bei verschiedenerURL– und lesen und schreiben dann still die Daten des ersten Dienststamms. Der Treiber erfährt davon nichts und kann es nicht verhindern; die Regel für die Einrichtung steht unter Mehrere Dienststämme in einer Datei. Ebenso teilen sich Verknüpfungen, die sich nur inROLE=unterscheiden, eine Verbindung; dann gilt die Datenbank-Identität der ersten. Verschiedene Dienststämme und eine zweite Identität in derselben Sitzung brauchen deshalb verschiedeneDATABASE-Werte; der Treiber ergänzt einen, wenn die Zeichenfolge keinen nennt. Siehe Verbindungszeichenfolge des Treibers. - Der Dialog erscheint nur, wo die Anwendung ihn zulässt: mit einem Fenster und nicht mit
SQL_DRIVER_NOPROMPT. Ohne Fenster scheitert eine unvollständige Verbindung mit der Abweisung des Dienstes. Öffnet Access eine Verknüpfung ohne gespeichertes Kennwort, meldet sich der Treiber mit dem zuletzt benutzten Namen an, dessen Kennwort mit „Kennwort speichern“ abgelegt ist; sonst fragt er mit einem kurzen Anmeldeformular. Nach „Abbrechen“ fragt er für denselben Dienst fünf Sekunden lang nicht erneut. - Access zeigt beim gescheiterten Verbindungsaufbau nur DAO 3151; siehe Fehlerbehebung.
- Eine durchgereichte Anweisung beschreibt der Dienst vor dem Ausführen. Fragt eine Anwendung zwischen
SQLPrepareundSQLExecutenach den Spalten, holt der Treiber die Beschreibung beim Dienst, ohne die Anweisung auszuführen. Das geschieht nur, wenn der Dienst die Adresse für eigene Anweisungen selbst nennt (Store.PassThrough); mit einer Adresse ausPASSTHROUGHund bei einer Anweisung, die SQL Server nicht ohne Ausführen beschreiben kann (temporäre Tabellen), meldet der Treiber bis zum Ausführen null Spalten. - Nur die erste Ergebnismenge kommt Zeile für Zeile. Jede weitere Menge einer durchgereichten Anweisung trifft mit dem Ende der ersten ein und liegt im Speicher, bis die Anwendung sie mit
SQLMoreResultserreicht. Eine große Menge gehört deshalb an die erste Stelle der Prozedur. - DAO
GetRowshängt bei einem Fehler beim Weiterlesen – mit jedem Treiber; siehe Fehlerbehebung. - Eine durchgereichte Anweisung wird ganz gelesen. Es gibt keine Folgeseiten: Die Menge bestimmt die Anweisung selbst, und der Dienst begrenzt sie über seine Zeilenobergrenze. Greift diese Grenze, liefert der Treiber die gelieferten Zeilen und meldet danach
HY000„Der Dienst hat das Ergebnis nach N Zeilen gekürzt …“; Access zeigt das als „ODBC-Aufruf fehlgeschlagen“. Siehe Antworten einordnen. - Nur abbildbare Teile des OData-Modells erscheinen. Komplexe Werte, Sammlungen, Beziehungen, Singletons, Funktionen und vererbte Eigenschaften fehlen im Katalog; siehe Wie aus einem OData-Dienst ein relationales ODBC-Modell wird.
- Ein gebundener Binärwert reist als Text. Auf dem Durchreichepfad wird er base64-kodiert übergeben; eine Anweisung, die einen Binärwert vergleichen muss, sollte ihn selbst hinschreiben.
Betrieb
- Ablaufverfolgung: Zur Fehlersuche dienen die Ablaufverfolgung des Treibers und die des Treibermanagers; siehe Die Ablaufverfolgung einschalten. Die Spur hält ihre Datei offen, solange der Prozess läuft, und schreibt jede Zeile sofort.
- Ein Aufruf blockiert den Thread der Anwendung wie bei einem nativen Treiber, bis die Antwort da ist, und verarbeitet währenddessen keine Fensternachrichten. Ereignisse der Anwendung, etwa „Beim Anzeigen“ eines Datenblatts in Access, laufen deshalb nie mitten in einem Treiberaufruf.
- Zertifikate: Über
httpsprüft der Treiber das Zertifikat gegen die Zertifikatsspeicher von Windows, ohne Schalter zum Abschalten; ein nicht vertrautes Zertifikat ergibt08S01und wird nicht wiederholt. Siehe 08S01 „UntrustedRoot“. Schemaänderungen: Der Treiber lädt
$metadataeinmal je Verbindung und hält es, bis die Verbindung geschlossen wird. Ändert sich das Schema des Dienstes, solange eine Anwendung verbunden ist:Änderung Folge bis zum Neuaufbau Spalte oder Tabelle hinzugefügt nicht sichtbar Spalte entfernt oder umbenannt eine Anfrage, die sie nennt, lehnt der Dienst ab; die Anwendung erhält die Meldung des Dienstes Recht entzogen der Dienst lehnt ab ( 403), auch wenn die Tabelle noch angezeigt wirdNeu aufbauen heißt in Access: Access schließen und neu öffnen, danach im Tabellenverknüpfungs-Manager die betroffenen Verknüpfungen aktualisieren; erst dann übernimmt Access neue Spalten und Typen in die Verknüpfung.
Abweichungen von ODBC Driver 18
Wer eine Anwendung vom ODBC-Treiber von SQL Server (ODBC Driver 18) auf diesen Treiber umstellt, erhält über die Durchreiche dieselben Werte, wo beide Treiber ein Ergebnis liefern. In folgenden Punkten verhält sich dieser Treiber anders, in der x86- wie in der x64-Version:
| Bereich | ODBC Driver 18 | dieser Treiber |
|---|---|---|
Ausgabeparameter decimal, numeric | mit Genauigkeit und Skala der Bindung | als decimal(38,10): mehr als zehn Nachkommastellen werden gerundet |
Ausgabeparameter datetimeoffset | mit Versatz | ohne Versatz |
Ausgabeparameter als Datenstrom (SQL_PARAM_OUTPUT_STREAM) | unterstützt | HYC00 |
Zähler einer Änderung zwischen Ergebnismengen (ohne SET NOCOUNT ON) | je ein eigenes Ergebnis für SQLMoreResults | übergangen; SQLMoreResults springt zur nächsten Menge mit Spalten |
Spalten nach SQLPrepare mit einer Adresse aus PASSTHROUGH | beschrieben | null Spalten bis zum Ausführen |
varchar(max) | SQL_VARCHAR mit Länge 0 | SQL_LONGVARCHAR mit Länge 2 147 483 647 (gewollt, siehe Datentypen) |
| Spalte ohne Namen oder mit doppeltem Namen in einer durchgereichten Abfrage | leerer bzw. doppelter Name | der Name aus label; ein Dienst ohne label vergibt eigene Namen (etwa Column2, Nummer1), siehe Anforderungen an einen OData-Dienst |
xml in einer durchgereichten Abfrage | gespeicherter Text | der Text, den der Dienst liefert; der Datendienst Wkl.Data.Gateway schreibt ein leeres Element als <r /> statt <r/> (dasselbe Dokument) |
Deskriptorfelder (SQLGetDescField, SQLSetDescField) | geführt | HYC00 |