KSQL-Treiber
Eigene Treiber für den KSQL-Port (TDS 7.4 mit dem KSQL-Profil) in acht Sprachen, je nach dem Vorbild des Microsoft-Treibers: dieselbe Schnittstelle, dieselben Schlüssel der Verbindungszeichenfolge, dieselbe Abbildung der Typen und Fehler — und dazu, was KSQL über SQL Server hinaus kann. Jeder arbeitet auch an SQL Server. Jeder Treiber spielt denselben sprachneutralen Prüfkatalog ab (KuonenSQL/tools/ksql-konformitaet/faelle.json, D36.1), einmal gegen den KSQL-Port und einmal gegen SQL Server 2025.
Vorbild: ODBC Driver 18 for SQL Server · libksqlodbc (ODBC 3.8) auf dem Protokollkern libksqlkern (C11) · CMake; Linux mit unixodbc-dev und libssl-dev, Windows mit dem SDK (SChannel), macOS mit Secure Transport und den Köpfen von unixODBC oder iODBC · Quelle: Data/src/Kuonen.Data.Ksql.Odbc, Data/src/Kuonen.Data.Ksql.C
· Roadmap D36.5 ✅
Herunterladen und einbinden
- kuonen-ksql-odbc-2.8.0.1-linux-x64.tar.gz · 108 KB
SHA-256
c10d90a442832aca382b51895ce39f9138eaf507c09a0c993d541d7779a5132c
sudo mkdir -p /opt/ksql && sudo tar -xzf kuonen-ksql-odbc-2.8.0.1-linux-*.tar.gz -C /opt/ksql
printf '[Kuonen KSQL ODBC Driver]\nDriver=/opt/ksql/libksqlodbc.so\nThreading=0\n' | sudo tee -a /etc/odbcinst.ini
# Verbindung: DRIVER={Kuonen KSQL ODBC Driver};Server=…,1333;…Der ODBC-Treiber als Bibliothek für Linux, x64 oder arm64 je nach Server (unixODBC, OpenSSL 3). Für Windows und macOS gibt es noch keinen Download (D36.5e).
Aus dem Quellcode bauen
cmake -S Data/src/Kuonen.Data.Ksql.Odbc -B bau -DCMAKE_BUILD_TYPE=Release && cmake --build bau
# odbcinst.ini (Linux)
[Kuonen KSQL ODBC Driver]
Driver=/pfad/libksqlodbc.so
Threading=0Threading=0, damit SQLCancel aus einem zweiten Faden am Treibermanager vorbeikommt. Der Kern allein: cmake -S Data/src/Kuonen.Data.Ksql.C -B bau [-DKSQL_TLS=openssl|apple|schannel] ergibt libksqlkern.a.
Verbindungszeichenfolge
Driver={Kuonen KSQL ODBC Driver};Server=tcp:localhost,1333;UID=sa;PWD=<Ihr-Kennwort>;TrustServerCertificate=yesOhne Port gilt 1433 wie beim Vorbild; den KSQL-Port 1333 nennt man.
| Schlüssel | Bedeutung |
|---|---|
Server (Address, Addr) | [tcp:]Rechner[\Instanz][,Port]; . und (local) sind localhost; eine Instanz ohne Port fragt den SQL Browser (UDP 1434) |
UID, PWD, Database | SQL-Anmeldung (Authentication=SqlPassword oder ohne) |
Encrypt | yes/mandatory (Vorgabe), no/optional, strict (TDS 8.0) |
TrustServerCertificate, HostNameInCertificate, ServerCertificate | Prüfung des Zertifikats; ServerCertificate heftet es an (PEM oder DER) |
APP, WSID, Language, ApplicationIntent, LoginTimeout, PacketSize | wie bei ODBC Driver 18 |
DSN | liest dieselben Schlüssel aus odbc.ini |
Beispiel: verbinden, abfragen, Parameter, Transaktion
SQLDriverConnect(dbc, NULL, (SQLCHAR *)"Driver={Kuonen KSQL ODBC Driver};Server=tcp:localhost,1333;"
"UID=sa;PWD=…;TrustServerCertificate=yes", SQL_NTS, NULL, 0, NULL, SQL_DRIVER_NOPROMPT);
SQLSetConnectAttr(dbc, SQL_ATTR_AUTOCOMMIT, (SQLPOINTER)SQL_AUTOCOMMIT_OFF, 0);
SQLAllocHandle(SQL_HANDLE_STMT, dbc, &st);
SQLPrepare(st, (SQLCHAR *)"SELECT name FROM sys.tables WHERE name LIKE ?", SQL_NTS);
SQLCHAR muster[] = "kk_%"; SQLLEN laenge = SQL_NTS;
SQLBindParameter(st, 1, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_VARCHAR, 64, 0, muster, 0, &laenge);
SQLExecute(st);
while (SQL_SUCCEEDED(SQLFetch(st))) { /* SQLGetData … */ }
SQLCloseCursor(st);
SQLEndTran(SQL_HANDLE_DBC, dbc, SQL_COMMIT);
if (SQLExecDirect(st, (SQLCHAR *)"SELECT 1 / 0", SQL_NTS) == SQL_ERROR) {
SQLCHAR zustand[6], text[512]; SQLINTEGER nummer; /* zustand "22012", nummer 8134 */
SQLGetDiagRec(SQL_HANDLE_STMT, st, 1, zustand, &nummer, text, sizeof text, NULL);
}Typen
| SQL- bzw. KSQL-Typ | im Treiber |
|---|---|
| Typen von SQL Server | die ODBC-Typen und SQL_SS_TIME2, SQL_SS_TIMESTAMPOFFSET, SQL_SS_XML, SQL_SS_VARIANT, SQL_SS_UDT mit SQL_SS_TIME2_STRUCT und SQL_SS_TIMESTAMPOFFSET_STRUCT (include/ksqlodbc.h) |
| INTERVAL, DECFLOAT, ROW, ARRAY, MULTISET | SQL_WVARCHAR mit ihrem Text; der Typname steht in SQL_DESC_TYPE_NAME |
| money, smallmoney, datetime, smalldatetime als Parameter | eigene Erweiterung SQL_CA_KSQL_SERVERTYP im IPD (mit SQL_DECIMAL bzw. SQL_TYPE_TIMESTAMP) |
| Kern: ksql_als_text | jeder Wert in der kanonischen Form des Prüfkatalogs; dazu …_ganzzahl, …_gleitkomma, …_dezimal, …_zeitpunkt, …_utf8 |
Fehler und SQLSTATE
| Fall | Angaben |
|---|---|
| SQLGetDiagRec, SQLGetDiagField | mit SQL_DIAG_SS_SEVERITY, SQL_DIAG_SS_MSGSTATE, SQL_DIAG_SS_LINE, SQL_DIAG_SS_PROCNAME, SQL_DIAG_SS_SRVNAME |
| SQLSTATE am KSQL-Port | der vom Meldungsende; fehlt er, HY000 |
| SQLSTATE an SQL Server | wie der Microsoft-Treiber aus der Nummer |
| Treiber und Kern | HY008 Abbruch, HYT00 Frist, 08S01 Leitungsstörung (eine unlesbare Antwort ist nie ein Absturz), 01S00 bei MARS_Connection=yes, 28000 bei Windows- oder Entra-Anmeldung |
Unterschiede zu ODBC Driver 18 for SQL Server
- Dieselben Verbindungsschlüssel, SQLGetInfo, Typabbildung und Massenkopie (bcp_initA/W, bcp_bind, bcp_sendrow, bcp_batch, bcp_done …) wie ODBC Driver 18.
- MARS_Connection=yes gibt einen Hinweis (01S00), die Verbindung arbeitet ohne MARS.
- Parameterfelder gehen Satz für Satz als eigene Anfrage (der Microsoft-Treiber bündelt sie in einen Stapel).
- Der Savepoint geht über SAVE TRANSACTION im Stapel (ODBC hat keine Funktion dafür).
- Eigene Erweiterung SQL_CA_KSQL_SERVERTYP für money/datetime-Parameter.
- Der Protokollkern libksqlkern trägt zugleich die PHP-Erweiterung und die C++-Schnittstelle.
Was fehlt
- Scrollbare Cursor, asynchrone Ausführung, SQLSetPos/SQLBulkOperations, SQLBrowseConnect, eigene Deskriptoren und SQLCopyDesc.
- MARS, Always Encrypted, Tabellenwertparameter, bcp mit Dateien, Windows- und Entra-Anmeldung.
- Andere Codepages als 1252 und UTF-8 bei char/varchar; Daten bei der Ausführung in Parameterfeldern, SQL_ATTR_PARAM_BIND_OFFSET_PTR.
- Nicht gelaufen: Windows (nur mit mingw-w64 übersetzt), macOS mit dem Treiber (nur der Kern).
| Restzeile | Beschreibung | Stand |
|---|---|---|
D36.5d Rest aus D36.5c | (1) Nicht gelaufen: Windows (nur mit mingw-w64 übersetzt und gelinkt; MSVC, SChannel und der Windows-Treibermanager ungeprüft), macOS mit dem Treiber (nur der Kern mit Secure Transport und OpenSSL; ODBC-Köpfe fehlen auf dem Mac); der SQL Browser nur gegen einen nachgebauten Browser im Test des Kerns. (2) Nicht im Treiber: ändernde Cursor (Keyset und dynamisch des Servers, `SQLSetPos` mit `SQL_UPDATE`/`SQL_DELETE`, `SQLBulkOperations` mit `SQL_ADD` und den Änderungen nach Lesezeichen), asynchrone Ausführung, `SQLBrowseConnect`, eigene Deskriptoren und `SQLCopyDesc`, MARS, Always Encrypted, `bcp` mit Dateien, Windows-/Entra-Anmeldung, andere Codepages als 1252 und UTF-8 bei `char`/`varchar`, Daten bei der Ausführung in Parameterfeldern und Tabellenwertparametern, Tabellenwertparameter in Parameterfeldern, `SQL_ATTR_PARAM_BIND_OFFSET_PTR`, `SQL_SOPT_SS_NAME_SCOPE` für Tabellentypen, `SQLGetData` stückweise vom Server (der Strommodus des Kerns wird im Treiber nicht genutzt). (3) Der statische Cursor hält die Menge im Speicher. (4) Parameterfelder gehen Satz für Satz als eigene Anfrage; Mengen der Sätze entfallen (`SQL_PAS_NO_SELECT`). (5) Befunde für den Server: `sp_describe_undeclared_parameters` antwortet leer; `UNION ALL` aus `varbinary(max)` und `0x01` meldet 8115; `SUBSTRING` über einen `varbinary(max)`-Parameter bricht den TDS-Strom (die Spalte wird zu kurz angekündigt, auch über sqlcmd); SQL Server nimmt alle drei an. (6) Der Savepoint geht über `SAVE TRANSACTION` im Stapel. **Erledigt 21.10.2026:** (5) am Orakel gemessen und nachgebaut: `sp_describe_undeclared_parameters` leitet die Typen nicht erklärter Parameter ab (einfache Ableitung bei =, <>, IN, Zuweisung, INSERT VALUES, CAST; allgemeine bei <, >, BETWEEN, LIKE und Rechnungen: decimal(38,19), varchar(8000), nvarchar(4000), datetime2(7) …; 11508, 11503, 11506) mit den 24 Spalten des Orakels; `SUBSTRING` über `varbinary(max)` bleibt `varbinary(max)` (vorher kündigte die Spalte 1 Byte an und der Wert brach den Strom); `UNION ALL` aus `varbinary(max)` und `0x01` geht am T-SQL-Port schon - am KSQL-Port ist `0x01` nach Profil eine Ganzzahl (T661), mit `X'01'` geht es dort ebenso, der Befund lag am Prüfprogramm. Tests `UndeklarierteParameterTests` (19, vorher 18 rot), `BinaerParameterTests` (6, vorher 3 rot). (1) bis (4) und (6) unverändert in D36.5e. | ✅ |
D36.5e Rest aus D36.5d | (1) Nicht gelaufen: Windows (nur mit mingw-w64 übersetzt und gelinkt; MSVC, SChannel und der Windows-Treibermanager ungeprüft), macOS mit dem Treiber (nur der Kern mit Secure Transport und OpenSSL; ODBC-Köpfe fehlen auf dem Mac); der SQL Browser nur gegen einen nachgebauten Browser im Test des Kerns. (2) Nicht im Treiber: ändernde Cursor (Keyset und dynamisch des Servers, `SQLSetPos` mit `SQL_UPDATE`/`SQL_DELETE`, `SQLBulkOperations` mit `SQL_ADD` und den Änderungen nach Lesezeichen), asynchrone Ausführung, `SQLBrowseConnect`, eigene Deskriptoren und `SQLCopyDesc`, MARS, Always Encrypted, `bcp` mit Dateien, Windows-/Entra-Anmeldung, andere Codepages als 1252 und UTF-8 bei `char`/`varchar`, Daten bei der Ausführung in Parameterfeldern und Tabellenwertparametern, Tabellenwertparameter in Parameterfeldern, `SQL_ATTR_PARAM_BIND_OFFSET_PTR`, `SQL_SOPT_SS_NAME_SCOPE` für Tabellentypen, `SQLGetData` stückweise vom Server (der Strommodus des Kerns wird im Treiber nicht genutzt). (3) Der statische Cursor hält die Menge im Speicher. (4) Parameterfelder gehen Satz für Satz als eigene Anfrage; Mengen der Sätze entfallen (`SQL_PAS_NO_SELECT`). (5) (erledigt in D36.5d) (6) Der Savepoint geht über `SAVE TRANSACTION` im Stapel. | ⬜ |
Herkunft und Lizenz
Eigenbau: übernommen sind nur die Schnittstelle des Microsoft-Treibers und das am Orakel (SQL Server 2025) gemessene Verhalten, kein Code – auch nicht aus MIT- oder BSD-lizenzierten Quellen –, damit der Treiber uneingeschränkt KuonenSQL gehört. Der Code bleibt geschlossen; eine Veröffentlichung gibt es nur als eigenständigen Fork, den Marc Kuonen selbst anlegt.
Eigener Code ohne fremde Quellen; fremd sind nur der Treibermanager (unixODBC, iODBC oder der von Windows) und die TLS-Bibliothek des Systems.