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: mssql-jdbc · Maven org.kuonen.ksql:kuonen-ksql-jdbc, Paket org.kuonen.ksql.jdbc · Java 17+, JDBC 4.3 · Quelle: Data/src/Kuonen.Data.Ksql.Java, Data/src/Kuonen.Data.Ksql.Java.Flyway · Roadmap D36.2 ✅

Herunterladen und einbinden

Befehle
# Maven: ins lokale Repository übernehmen, dann als Abhängigkeit org.kuonen.ksql:kuonen-ksql-jdbc:2.0.0
mvn install:install-file -Dfile=kuonen-ksql-jdbc-2.0.0.jar -DgroupId=org.kuonen.ksql -DartifactId=kuonen-ksql-jdbc -Dversion=2.0.0 -Dpackaging=jar
# Gradle: implementation(files("libs/kuonen-ksql-jdbc-2.0.0.jar"))
# ohne Werkzeug:
java -cp kuonen-ksql-jdbc-2.0.0.jar:. MeinProgramm

Ein JAR ohne Abhängigkeiten (Java 17+); es meldet sich selbst bei DriverManager an, die URL beginnt mit jdbc:ksql:. Die Flyway-Erweiterung gibt es nur aus dem Quellcode.

Aus dem Quellcode bauen

Befehle
cd Data/src/Kuonen.Data.Ksql.Java && mvn install      # org.kuonen.ksql:kuonen-ksql-jdbc
sh Data/src/Kuonen.Data.Ksql.Java/pruefen.sh          # ohne Maven: nur javac und jar aus dem JDK 17+, mit den eigenen Prüfungen
cd Data/src/Kuonen.Data.Ksql.Java.Flyway && mvn install   # org.kuonen.ksql:kuonen-ksql-flyway (nur für Flyway)

Ohne Fremdabhängigkeiten; der Treiber meldet sich über META-INF/services bei java.sql.DriverManager an. Für Flyway 10 gibt es die Erweiterung kuonen-ksql-flyway (eigenes JAR neben dem Treiber, D36.8a): sie meldet über META-INF/services den Datenbanktyp „KuonenSQL“ für jdbc:ksql: an, setzt auf flyway-sqlserver auf und lässt die Engine Edition 100 zu; Flyway bringt die Anwendung mit, der Treiber selbst bleibt ohne Abhängigkeiten. Spring JDBC (D36.8g) kennt den Produktnamen „KuonenSQL“ nicht: für die Übersetzung der Fehlernummern die Vorlage Data/src/Kuonen.Data.Ksql.Java/spring/sql-error-codes.xml als sql-error-codes.xml in den Klassenpfad der Anwendung legen (oder ihre Bean in eine vorhandene übernehmen); SimpleJdbcCall liest die Parameter einer Prozedur nur bei Produkten, die Spring kennt, darum mit withoutProcedureColumnMetaDataAccess() und erklärten Parametern (declareParameters) aufrufen. Ein README hat der Treiber nicht; die Angaben stammen aus dem Code und der Roadmap-Zeile D36.2.

Verbindungszeichenfolge

jdbc:ksql://localhost;databaseName=master;user=sa;password=<Ihr-Kennwort>;encrypt=true;trustServerCertificate=true

Ohne Port gilt 1333 (der KSQL-Port).

SchlüsselBedeutung
URLjdbc:ksql://[server][\instanz][:port][;schlüssel=wert]…, Schlüssel ohne Rücksicht auf Gross- und Kleinschreibung, {…} erlaubt ; im Wert
serverName (server), portNumber (port), instanceNameRechner, Port (Vorgabe 1333), benannte Instanz (wird über den SQL Browser nicht aufgelöst)
databaseName (database)Anfangsdatenbank
user (userName), passwordSQL-Anmeldung
encrypttrue/mandatory/yes (Vorgabe), false/optional/no (nur die Anmeldung verschlüsselt), strict (TDS 8)
trustServerCertificate, hostNameInCertificatePrüfung des Zertifikats
loginTimeout, queryTimeout, socketTimeoutFristen (15 s, ohne, ohne)
applicationName, workstationID, packetSize, applicationIntentwie bei mssql-jdbc
sendStringParametersAsUnicode, lastUpdateCountwie bei mssql-jdbc (Vorgabe true)

Beispiel: verbinden, abfragen, Parameter, Transaktion

Java
import java.sql.*;

try (Connection c = DriverManager.getConnection(
        "jdbc:ksql://localhost;databaseName=master;encrypt=true;trustServerCertificate=true", "sa", "…")) {
    c.setAutoCommit(false);
    try (PreparedStatement s = c.prepareStatement("SELECT name FROM sys.tables WHERE name LIKE ?")) {
        s.setString(1, "kk_%");
        try (ResultSet r = s.executeQuery()) {
            while (r.next()) System.out.println(r.getString(1));
        }
    }
    Savepoint vorher = c.setSavepoint("vorher");
    c.commit();

    try (Statement s = c.createStatement()) {
        s.executeQuery("SELECT 1 / 0");
    } catch (SQLException e) {          // e.getErrorCode() 8134, e.getSQLState() "22012"
        System.out.println(e.getErrorCode() + " " + e.getSQLState());
    }
}

Typen

SQL- bzw. KSQL-Typim Treiber
Typen von SQL Serverdie Typtabelle von JDBC (java.sql.Date, Time, Timestamp, BigDecimal …); Types mit den Werten von microsoft.sql.Types
datetimeoffsetorg.kuonen.ksql.sql.DateTimeOffset (wie microsoft.sql.DateTimeOffset)
BOOLEANBoolean
INTERVAL …KsqlInterval (Monate und Zeitspanne; als Duration, wenn keine Monate)
DECFLOATBigDecimal
ROW(…)KsqlStruct als java.sql.Struct, getSQLTypeName() in der Schreibweise der Norm
typ ARRAY / typ MULTISETKsqlArray als java.sql.Array, getBaseTypeName() der Elementtyp; Connection.createArrayOf und createStruct legen sie an

Fehler und SQLSTATE

FallAngaben
SQLServerException (wie bei mssql-jdbc)getErrorCode() ist die Nummer des Servers, weitere Meldungen derselben Antwort hängen als getNextException() daran
getSQLState() am KSQL-Portder SQLSTATE der Norm vom Meldungsende (Profil 8.1, vom Text getrennt)
getSQLState() an SQL Serverwie mssql-jdbc (D36.2a gemessen): „S“ und der Zustand der Meldung vierstellig (2812 → S0062), 208 → S0002, 2714 → S0001, Verletzungen von Schlüssel, NOT NULL und Fremdschlüssel → 23000

Unterschiede zu mssql-jdbc

  • URL jdbc:ksql:// statt jdbc:sqlserver://, dieselben Schlüssel; Vorgabeport 1333 statt 1433.
  • Klassen mit den Namen von mssql-jdbc (SQLServerDriver, SQLServerDataSource, SQLServerBulkCopy, ISQLServerBulkData …) unter dem eigenen Paket org.kuonen.ksql.jdbc.
  • DatabaseMetaData über sp_tables, sp_columns, sp_pkeys usw. mit denselben Spalten in derselben Reihenfolge und denselben Typen wie mssql-jdbc (D36.2a an SQL Server 2025 gemessen: getTables mit fünf Spalten, getColumns mit den SS_-Zusatzspalten, getFunctions über sp_stored_procedures).
  • Am KSQL-Port zusätzlich SQLSTATE der Norm, BOOLEAN, INTERVAL, DECFLOAT, ROW/ARRAY/MULTISET mit den Typnamen der Norm.
  • Unter TLS geht jedes Paket in genau einem Record (höchstens 16 384 Bytes, unter TLS 1.3 16 367) – SQL Server schliesst sonst die Verbindung.

Was fehlt

  • MARS, rollbare und änderbare Ergebnismengen, Clob/Blob/SQLXML als Objekte.
  • Always Encrypted, Tabellenwertparameter, integrierte Anmeldung und Entra ID, XA.
  • TDS 8 am Orakel (am KSQL-Port und mit einem TLS-Spielserver geprüft).
  • Verteilung über Maven Central.
RestzeileBeschreibungStand
D36.2a Rest aus D36.2**Teilweise erledigt 21.10.2026:** (1) Der Katalog läuft mit dem Java-Treiber auch am Orakel 14335 (Kennwort zur Laufzeit aus dessen Container): 72 ok, 0 abweichend, 10 übersprungen (nur KSQL) - erst nach drei Korrekturen, die der KSQL-Port nicht zeigte: der TLS-Handschlag ging als eine PRELOGIN-Nachricht je Record (SQL Server schloss jede Verbindung), der Name eines Sicherungspunkts mit seiner Länge in Zeichen statt Bytes (3979), die Massenkopie mit festen Merkmalen statt denen der Zielspalte (4816). (2) Docker: der Prüfstand `java/` baut mit JDK 17 (16 Prüfungen) und spielt den Katalog als Bauschritt an beiden Zielen ab; `docker run` steht weiter aus. (3) TDS 8 (`encrypt=strict`): TLS 1.2/1.3 vor dem ersten Paket mit ALPN `tds/8.0`, PRELOGIN im Tunnel; geprüft mit einem TLS-Spielserver und am KSQL-Port, am Orakel schliesst SQL Server den TLS-Aufbau (wie beim C-Kern; der Container hat kein Zertifikat für TDS 8). Dazu: unter TLS 1.3 höchstens 16 367 Bytes je Paket, und `encrypt=true` fällt nicht mehr still auf die verschlüsselte Anmeldung allein zurück. **Offen:** die Abbildung Nummer → SQLSTATE an SQL Server und die Spaltenreihenfolge der Zusatzspalten von `DatabaseMetaData` sind nicht gegen mssql-jdbc gemessen; TDS 8 am Orakel; MARS, rollbare und änderbare Ergebnismengen, SQLXML als Objekt (Clob/NClob/Blob seit D36.8f), Always Encrypted, Tabellenwertparameter, integrierte Anmeldung und Entra ID, XA; Verteilung über Maven Central. **Erledigt 21.10.2026** (mit Docker, Freigabe Marc): (2) der Prüfstand `java/` lief als Test (`TreiberPruefstandTests`) am Prüfserver und am Orakel grün. SQLSTATE und DatabaseMetaData gegen mssql-jdbc 12.8.1 gemessen (Programm `abnahme.Vergleich` im Abnahmeabbild, beide Treiber am selben Orakel, 37 Fehler und 25 Methoden): mssql-jdbc bildet den SQLSTATE aus „S“ und dem Zustand der Meldung (2812 Zustand 62 → `S0062`, RAISERROR Zustand 27 → `S0027`), ausser 208 → `S0002`, 2714 → `S0001` und 2627/2601/515/547 → `23000`; der eigene Treiber tut das jetzt an SQL Server ebenso (am KSQL-Port bleibt der SQLSTATE der Norm). DatabaseMetaData liefert dieselben Spalten in derselben Reihenfolge mit denselben Typen (getTables nur die fünf Spalten von sp_tables, getColumns mit SS_IS_SPARSE … SS_XML_SCHEMACOLLECTION_NAME statt SS_DATA_TYPE, getProcedures ohne SPECIFIC_NAME, getProcedureColumns mit den SS_-Spalten, getFunctions über sp_stored_procedures, Fremdschlüsselregeln als int, leere Mengen mit char/int, getClientInfoProperties leer); danach sind beide Ausgaben gleich. `PruefungenTest` (18, vorher 1 rot); Hibernate, Flyway und Spring am KSQL-Port weiter grün. Rest in D36.2e.✅
D36.2d Rest aus D36.2c: verteilte TransaktionenNicht ohne MS DTC nachzubauen: Art 3 beantwortet SQL Server mit einer Menge „TM Address“ (die Adresse seines DTC), TM_PROMOTE_XACT in einer Transaktion mit ENVCHANGE 15 und einem DTC-Token, TM_PROPAGATE_XACT mit einem DTC-Puffer bindet die Sitzung an eine verteilte Transaktion; der KSQL-Port antwortet darauf mit einem leeren DONE. Erst mit einem eigenen Koordinator (oder der Entscheidung, sie abzuweisen) sinnvoll.⬜
D36.2e Rest aus D36.2aTDS 8 (`encrypt=strict`) am Orakel nicht geprüft (der Container hat kein Zertifikat für TDS 8); nicht gebaut: MARS, rollbare und änderbare Ergebnismengen, SQLXML als Objekt, Always Encrypted, Tabellenwertparameter, integrierte Anmeldung und Entra ID, XA; Verteilung über Maven Central (Entscheid Marc, Code bleibt geschlossen). Der SQLSTATE von 1205 (`40001`) und der Anmeldefehler ist nicht gegen mssql-jdbc gemessen.⬜

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.

Rund 11 500 Zeilen eigener Code, TDS 7.4 samt TLS im PRELOGIN selbst; ohne Fremdabhängigkeiten. Nicht auf Maven Central.