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: go-mssqldb · Modul kuonen.org/ksql, database/sql-Treiber ksql · Go 1.23, nur Standardbibliothek (TLS über crypto/tls) · Quelle: Data/src/Kuonen.Data.Ksql.Go · Roadmap D36.7 ✅

Herunterladen und einbinden

Kein Download: ein Go-Modul ist Quelltext, und der Code bleibt geschlossen; das Modul kuonen.org/ksql braucht erst einen Ort, der den Importpfad ausliefert (Entscheid von Marc Kuonen).

Aus dem Quellcode bauen

Befehle
cd Data/src/Kuonen.Data.Ksql.Go && go vet ./... && go test ./...
# im eigenen Modul: import _ "kuonen.org/ksql"

Das Modul kuonen.org/ksql braucht einen Ort, der den Importpfad ausliefert – erst nach Entscheid von Marc (Code bleibt geschlossen).

Verbindungszeichenfolge

server=localhost,1333;user id=sa;password=<Ihr-Kennwort>;encrypt=true;TrustServerCertificate=true

Ohne Port gilt 1333 (der KSQL-Port).

SchlüsselBedeutung
ADO-Formserver=host,port; user id; password; database; encrypt; TrustServerCertificate; hostNameInCertificate; connection timeout; app name; workstation id; packet size; ApplicationIntent
URLsqlserver://… bzw. ksql://benutzer:kennwort@host:port?database=…
PortVorgabeport 1333
encryptdisable, false (nur die Anmeldung), true (Vorgabe), strict (TDS 8.0)

Beispiel: verbinden, abfragen, Parameter, Transaktion

Go
import (
	"database/sql"
	"errors"
	"kuonen.org/ksql"
)

db, _ := sql.Open("ksql", "server=localhost,1333;user id=sa;password=…;encrypt=true;TrustServerCertificate=true")
var n int64
db.QueryRow("SELECT @p1 + @wert", 1, sql.Named("wert", 41)).Scan(&n)

tx, _ := db.BeginTx(ctx, nil)                 // Transaction-Manager-Anfrage
tx.Exec("UPDATE konto SET saldo = saldo - @p1 WHERE id = @p2", 1, 7)
tx.Commit()

var e ksql.Error
if _, err := db.Exec("SELECT 1 / 0"); errors.As(err, &e) {
	fmt.Println(e.Number, e.SQLState)          // 8134 22012
}

Typen

SQL- bzw. KSQL-Typim Treiber
Parameterwie go-mssqldb: int64 → bigint, string → nvarchar, time.Time → datetimeoffset, VarChar, VarCharMax, NVarCharMax, NChar, DateTime1, DateTimeOffset, UniqueIdentifier; dazu ksql.TypedValue{SQLType: "decimal(9,2)", Value: "1.10"}
WerteGanzzahlen int64, bit bool, float/real float64, Zeichen string, Binär []byte, Zeitwerte time.Time (100 ns genau), uniqueidentifier die 16 Byte der Leitung (ksql.UniqueIdentifier.Scan)
decimal, money, DECFLOATText in []byte wie go-mssqldb (Scan in string oder float64)
INTERVAL, ROW, ARRAY, MULTISETText; Rows.ColumnTypeDatabaseTypeName nennt den Namen auf der Leitung (INTERVAL DAY(2))

Fehler und SQLSTATE

FallAngaben
ksql.Errordie Felder von mssql.Error: Number, State, Class, Message, ServerName, ProcName, LineNo, All
SQLStateam KSQL-Port der vom Meldungsende; an SQL Server aus der Nummer wie die ODBC-Treiber von Microsoft (ohne Eintrag 42000)
ServerSQLStateder Zustand vom Meldungsende des KSQL-Ports; an SQL Server leer
Abbruch, Fristüber den Kontext: ATTENTION, dann context.Canceled bzw. context.DeadlineExceeded; die Verbindung bleibt benutzbar

Unterschiede zu go-mssqldb

  • Treibername ksql statt sqlserver; Vorgabeport 1333.
  • Ausgaben mit sql.Out, Rückgabestatus mit *ksql.ReturnStatus, ein einzelner Name als Anweisung geht als RPC (wie go-mssqldb).
  • Massenkopie über ksql.CopyIn, Meldungen über ksql.WithMessages(ctx, …), Savepoint/RollbackTo über sql.Conn.Raw.
  • Zusätzlich SQLState (Norm) und ServerSQLState am Fehler.

Was fehlt

  • Benannte Instanzen (SQL Browser), Windows- und Entra-Anmeldung, MARS, Umleitung.
  • Always Encrypted, Tabellenwertparameter.
  • Zeichentypen mit einer Codepage ausser 1252 und UTF-8 (sie kommen als []byte).
RestzeileBeschreibungStand
D36.7f Rest aus D36.7e(1) `docker run` startete am 21.10. keinen Container; `pruefstand.ps1` und ein Test wie `DockerPruefstandTests` für Python und Go sind noch nicht durchgelaufen (die Läufe gingen als Bauschritte). (2) Beide: keine Windows- oder Entra-Anmeldung, kein Always Encrypted; Go: `TVP` nicht als `sql.Out`; der SQL Browser nur gegen einen nachgebauten, nicht gegen einen echten SQL-Server-Browser; die Umleitung nur gegen einen falschen Server (der KSQL-Port leitet nur bei Lesezugriff auf eine Kopie um). (3) Python liest Codepages über `codecs`: undefinierte Byte werden zum Ersatzzeichen bzw. zum Byte gleicher Nummer, SQL Server nennt dafür teils Zeichen der privaten Zone (Messung in D36.7e). (4) Verteilung: das Python-Paket trägt „Private :: Do Not Upload“, das Go-Modul `kuonen.org/ksql` braucht einen Ort, der den Importpfad ausliefert - beides erst nach Entscheid von Marc (Code bleibt geschlossen). (5) `tools/roadmap.py` braucht Python 3.10+, lokal gibt es 3.9: Status von Hand gesetzt, `nachziehen` nicht gelaufen. **Erledigt 21.10.2026:** (1) `PythonGoPruefstandTests` (Bauschritt wie `OdbcPruefstandTests`, `KUONENSQL_DOCKER_ABNAHME=1`): Python (`python:3.12-slim`, 23 Tests im Bau) und Go (`golang:1.23`, gofmt, vet, Tests im Bau) bestehen den Katalog am KSQL-Port (0 abweichend, 0 übersprungen) und an SQL Server 2025 (nur die Fälle „nur ksql“ übersprungen) - 4 von 4 grün. Dafür liegen die Go-Quellen mit LF im Arbeitsbaum (`.gitattributes` des Treibers; unter Windows scheiterte `gofmt -l` an CRLF) und beide Abbilder haben ein `Dockerfile.dockerignore`. (3) Am Orakel gemessen (je eine Datenbank in der Sortierung, alle Byte 0x80-0xFF von 12 Einzelbyte-Codepages): abweichend von den Codecs nur 874 (DB-DE, FC-FF → U+F8C1-F8C8), 1253 (AA, D2, FF → U+F8F9-F8FB), 1255 (CA → U+05BA, D9-DF, FB, FC, FF → U+F88D-F896) und 1257 (A1, A5 → U+F8FC, F8FD); der Python-Treiber liest sie so und schreibt sie zurück zu ihrem Byte (je Codepage ein Fehlerbehandler `ksql-roh-<cp>`, Test `test_undefinierte_byte_der_codepages_wie_sql_server`, vorher rot; Sabotage ohne die Tabelle rot). (5) `tools/roadmap.py` läuft mit Python 3.14: `pruefen` bestätigt die von Hand gesetzten Stände der Meilensteine (nur Datum und Fassung der Kopfzeilen wären nachzuziehen). Python lokal (3.14) 24 Tests, 3 übersprungen. Rest in D36.7h.✅
D36.7h Rest aus D36.7f(1) Beide: keine Windows- oder Entra-Anmeldung, kein Always Encrypted; Go: `TVP` nicht als `sql.Out`; der SQL Browser nur gegen einen nachgebauten, nicht gegen einen echten SQL-Server-Browser; die Umleitung nur gegen einen falschen Server (der KSQL-Port leitet nur bei Lesezugriff auf eine Kopie um). (2) Mehrbyte-Codepages (932, 936, 949, 950): wie in D36.7e gemessen; die Byte ohne Zeichen in den Einzelbyte-Codepages 437, 850 und 1250-1258 ausser den gemessenen sind Zeichen gleicher Nummer. (3) **Entscheid von Marc:** Verteilung - das Python-Paket trägt „Private :: Do Not Upload“, das Go-Modul `kuonen.org/ksql` braucht einen Ort, der den Importpfad ausliefert (Code bleibt geschlossen).⬜

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.

Kein Code von go-mssqldb; nur Standardbibliothek. Kein öffentlicher Ort für den Importpfad.