Kuonen SQL

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

Befehle
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

Befehle
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=0

Threading=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=yes

Ohne Port gilt 1433 wie beim Vorbild; den KSQL-Port 1333 nennt man.

SchlüsselBedeutung
Server (Address, Addr)[tcp:]Rechner[\Instanz][,Port]; . und (local) sind localhost; eine Instanz ohne Port fragt den SQL Browser (UDP 1434)
UID, PWD, DatabaseSQL-Anmeldung (Authentication=SqlPassword oder ohne)
Encryptyes/mandatory (Vorgabe), no/optional, strict (TDS 8.0)
TrustServerCertificate, HostNameInCertificate, ServerCertificatePrüfung des Zertifikats; ServerCertificate heftet es an (PEM oder DER)
APP, WSID, Language, ApplicationIntent, LoginTimeout, PacketSizewie bei ODBC Driver 18
DSNliest dieselben Schlüssel aus odbc.ini

Beispiel: verbinden, abfragen, Parameter, Transaktion

C (ODBC)
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-Typim Treiber
Typen von SQL Serverdie 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, MULTISETSQL_WVARCHAR mit ihrem Text; der Typname steht in SQL_DESC_TYPE_NAME
money, smallmoney, datetime, smalldatetime als Parametereigene Erweiterung SQL_CA_KSQL_SERVERTYP im IPD (mit SQL_DECIMAL bzw. SQL_TYPE_TIMESTAMP)
Kern: ksql_als_textjeder Wert in der kanonischen Form des Prüfkatalogs; dazu …_ganzzahl, …_gleitkomma, …_dezimal, …_zeitpunkt, …_utf8

Fehler und SQLSTATE

FallAngaben
SQLGetDiagRec, SQLGetDiagFieldmit SQL_DIAG_SS_SEVERITY, SQL_DIAG_SS_MSGSTATE, SQL_DIAG_SS_LINE, SQL_DIAG_SS_PROCNAME, SQL_DIAG_SS_SRVNAME
SQLSTATE am KSQL-Portder vom Meldungsende; fehlt er, HY000
SQLSTATE an SQL Serverwie der Microsoft-Treiber aus der Nummer
Treiber und KernHY008 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).
RestzeileBeschreibungStand
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.