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: sqlsrv und pdo_sqlsrv · Erweiterung ksql: Funktionen sqlsrv_* und PDO-Treiber ksql: · PHP 8.2+ (gebaut und geprüft mit PHP 8.3 auf Linux), OpenSSL · Quelle: Data/src/Kuonen.Data.Ksql.Php · Roadmap D36.4 ✅

Herunterladen und einbinden

Kein Download: die PHP-Erweiterung wird aus dem Quellcode gebaut, und der Code bleibt geschlossen (ein PECL-Paket wäre Quelltext). Auf Anfrage bei Marc Kuonen.

Aus dem Quellcode bauen

Befehle
cd Data/src/Kuonen.Data.Ksql.Php && phpize && ./configure --enable-ksql && make && make install
echo extension=ksql > /etc/php/conf.d/ksql.ini

configure kopiert den Kern aus ../Kuonen.Data.Ksql.C nach kern/; der Port folgt darum dem Kern (ohne Angabe 1433). Die Fassung folgt der des Servers.

Verbindungszeichenfolge

ksql:Server=server,1333;Database=master;TrustServerCertificate=yes

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

SchlüsselBedeutung
Serverwie bei ODBC (Rechner\Instanz ohne Port fragt den SQL Browser); bei sqlsrv_connect das erste Argument, etwa tcp:server,1333
Database, UID, PWDAnmeldung (bei PDO Benutzer und Kennwort als Argumente)
EncryptVorgabe yes wie ODBC Driver 18, auch strict
TrustServerCertificate, HostNameInCertificate, ServerCertificatePrüfung des Zertifikats
LoginTimeout, APP, WSID, Language, ApplicationIntent, PacketSizewie bei sqlsrv
TransactionIsolation, ReturnDatesAsStringswie bei sqlsrv
KsqlCancelAfterMs, PDO::KSQL_ATTR_CANCEL_AFTER_MS, PDO::KSQL_ATTR_QUERY_TIMEOUTeigene: Abbruch nach dieser Zeit (HY008), Befehlsfrist in Sekunden (HYT00)

Beispiel: verbinden, abfragen, Parameter, Transaktion

PHP
$c = sqlsrv_connect('tcp:server,1333', ['Database' => 'master', 'UID' => 'sa', 'PWD' => $pw, 'TrustServerCertificate' => true]);
$s = sqlsrv_query($c, 'SELECT name FROM sys.tables WHERE name LIKE ?', ['kk_%']);
while ($z = sqlsrv_fetch_array($s, SQLSRV_FETCH_ASSOC)) { echo $z['name'], "\n"; }

sqlsrv_begin_transaction($c);
sqlsrv_query($c, 'UPDATE konto SET saldo = saldo - ? WHERE id = ?', [1, 7]);
sqlsrv_commit($c);

if (sqlsrv_query($c, 'SELECT 1 / 0') === false) {
    print_r(sqlsrv_errors());              // SQLSTATE 22012, code 8134
}

// PDO
$pdo = new PDO('ksql:Server=server,1333;Database=master;TrustServerCertificate=yes', 'sa', $pw,
               [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]);
$s = $pdo->prepare('SELECT :a + 1 AS r');
$s->execute(['a' => 41]);

Typen

SQL- bzw. KSQL-Typim Treiber
sqlsrv: Ganzzahlen und bitint
sqlsrv: Gleitkommafloat
sqlsrv: Dezimal und GeldText
sqlsrv: ZeitDateTime (oder Text mit ReturnDatesAsStrings)
BinäresBytes
PDOWerte als Text wie pdo_sqlsrv (bit 1/0, Binäres als Bytes); PDO::PARAM_INT → int bzw. bigint, PARAM_STR → nvarchar, PARAM_BOOL → bit, PARAM_LOB → varbinary(max)
INTERVAL, DECFLOAT, ROW, ARRAY, MULTISETText in der kanonischen Form; sqlsrv_field_metadata nennt KsqlType (etwa INTERVAL DAY(2)) und KsqlTypeName, getColumnMeta ksql:type und ksql:decl_type

Fehler und SQLSTATE

FallAngaben
sqlsrv_errors()SQLSTATE, code, message wie sqlsrv; dazu severity und state
PDO::errorInfo, PDOExceptionSQLSTATE, Nummer, Text; dazu Klasse und Zustand in [3] und [4]
SQLSTATE am KSQL-Portder vom Meldungsende (aus dem Kern)
SQLSTATE an SQL Serverwie die Microsoft-Treiber aus der Nummer (Kern)

Unterschiede zu sqlsrv und pdo_sqlsrv

  • Eine Erweiterung für beide Schnittstellen: die sqlsrv_*-Funktionen und der PDO-Treiber mit DSN ksql: statt sqlsrv:.
  • Die Werte von SQLSRV_SQLTYPE_* und SQLSRV_PHPTYPE_* sind eigene Kodierungen; Programme, die die Namen nutzen, merken nichts.
  • SQLSRV_SQLTYPE_TIME(s), _DATETIME2(s), _DATETIMEOFFSET(s) mit Skala.
  • Eigene Massenkopie ksql_bulk_copy bzw. $pdo->ksqlBulkCopy(…) und $pdo->ksqlMeldungen() für PRINT und RAISERROR bis Klasse 10.
  • PHP hat keinen zweiten Faden für sqlsrv_cancel: dafür KsqlCancelAfterMs.
  • PDO::PARAM_STR geht als nvarchar, der Server wandelt in den deklarierten Typ (wie pdo_sqlsrv).

Was fehlt

  • Rollbare Cursor (Scrollable nur forward; sqlsrv_num_rows meldet das), Ströme (SQLSRV_PHPTYPE_STREAM liefert den ganzen Wert).
  • MARS, Verbindungspool, Windows- und Entra-Anmeldung, CharacterSet (immer UTF-8), Always Encrypted.
  • Verteilung: kein PECL-Paket (package.xml), kein Bau für Windows (config.w32) oder macOS; PHP 8.2 und 8.4 nicht gebaut.
RestzeileBeschreibungStand
D36.4c Rest aus D36.4b(1) Verteilung: kein PECL-Paket (`package.xml`) und kein Bau für Windows (`config.w32`, SChannel) oder macOS (Secure Transport); geprüft nur Linux arm64 mit PHP 8.3 (8.2 und 8.4 nicht gebaut). (2) Nicht in der Erweiterung: `CharacterSet` (immer UTF-8), MARS, Windows- und Entra-Anmeldung, Always Encrypted. (3) Rollbare Cursor sind immer statisch und halten die Menge im Speicher; ein Strom gilt nur, solange die Anweisung auf seiner Spalte steht; bei PDO strömt nur die letzte gebundene LOB-Spalte. (4) Der Pool gilt je Prozess und kennt keine Einstellung der Grösse oder Ruhezeit (`php.ini`). (5) Die Werte von `SQLSRV_SQLTYPE_*`/`SQLSRV_PHPTYPE_*` sind eigene Kodierungen (Programme nutzen die Namen; wer die Zahlen speichert, merkt den Unterschied zu sqlsrv). (6) `PDO::PARAM_STR` geht als `nvarchar` und der Server wandelt in den deklarierten Typ (wie pdo_sqlsrv); Typen ausserhalb dessen, was SQL Server so wandelt, brauchen `CAST` im Text. **Erledigt 21.10.2026:** (1) PECL-Paket: `paket.sh` baut `ksql-<Fassung>.tgz` mit `package.xml` (von `pecl package-validate` geprüft) und dem Kern unter `kern/`; `config.m4` legt die Unterordner für den Bau ausserhalb der Quellen an (`PHP_ADD_BUILD_DIR`, sonst scheiterte `pecl install`). Der Prüfstand `php/pecl.Dockerfile` installiert das Paket in einem frischen PHP 8.2, 8.3 und 8.4 (Linux x64) und lädt es. Der Prüfstand `php/Dockerfile` nimmt die PHP-Fassung als Bauargument; `PhpPruefstandTests` spielt den Katalog jetzt mit PHP 8.2, 8.3 und 8.4 am KSQL-Port und mit 8.3 am Orakel ab, jeweils samt `merkmale.php` (Tabellenwerte, Cursor, Ströme, Pool; 0 Fehlschläge) - alles grün. `merkmale.php` nahm am KSQL-Port `0x01` (dort eine Ganzzahl) und umging `SUBSTRING` über `varbinary(max)` (behoben in D36.5d). Rest in D36.4d.✅
D36.4d Rest aus D36.4c(1) Verteilung: kein Bau für Windows (`config.w32`, SChannel) oder macOS (Secure Transport); das PECL-Paket nur für den eigenen Gebrauch (Code bleibt geschlossen). (2) Nicht in der Erweiterung: `CharacterSet` (immer UTF-8), MARS, Windows- und Entra-Anmeldung, Always Encrypted. (3) Rollbare Cursor sind immer statisch und halten die Menge im Speicher; ein Strom gilt nur, solange die Anweisung auf seiner Spalte steht; bei PDO strömt nur die letzte gebundene LOB-Spalte. (4) Der Pool gilt je Prozess und kennt keine Einstellung der Grösse oder Ruhezeit (`php.ini`). (5) Die Werte von `SQLSRV_SQLTYPE_*`/`SQLSRV_PHPTYPE_*` sind eigene Kodierungen (Programme nutzen die Namen; wer die Zahlen speichert, merkt den Unterschied zu sqlsrv). (6) `PDO::PARAM_STR` geht als `nvarchar` und der Server wandelt in den deklarierten Typ (wie pdo_sqlsrv); Typen ausserhalb dessen, was SQL Server so wandelt, brauchen `CAST` im Text.⬜

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 PHP und OpenSSL. Kein PECL-Paket.