Description
When a non-ASCII (e.g. CJK) string is bound as a parameter against an nvarchar column on SQL Server via pdo_odbc + Microsoft ODBC Driver 18, the comparison never matches: = ? and LIKE ? both return zero rows, even though the row clearly exists. The same query with the same value works with pdo_sqlsrv.
The parameter appears to be bound as a non-Unicode (SQL_CHAR / ANSI) string rather than SQL_WCHAR, so the bytes sent to the server do not match the nvarchar (UTF-16) column data.
Reproduction (self-contained, no table required)
<?php
$dsn = "odbc:Driver={ODBC Driver 18 for SQL Server};Server=HOST,1433;Database=DB;Encrypt=no;TrustServerCertificate=yes;";
$pdo = new PDO($dsn, 'user', 'pass', [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]);
// The row value is a literal Unicode string; only the *bound parameter* differs.
$st = $pdo->prepare(
"SELECT COUNT(*) FROM (SELECT CAST(N'測試中文資料庫' AS nvarchar(100)) AS v) t WHERE v = ?"
);
$st->execute(['測試中文資料庫']);
var_dump($st->fetchColumn()); // expected 1, pdo_odbc returns 0
$st = $pdo->prepare(
"SELECT COUNT(*) FROM (SELECT CAST(N'測試中文資料庫' AS nvarchar(100)) AS v) t WHERE v LIKE ?"
);
$st->execute(['%中文%']);
var_dump($st->fetchColumn()); // expected 1, pdo_odbc returns 0
Observed vs expected
| query |
pdo_odbc |
pdo_sqlsrv |
expected |
WHERE v = ? bound '測試中文資料庫' |
0 |
1 |
1 |
WHERE v LIKE ? bound '%中文%' |
0 |
1 |
1 |
ASCII-only bound parameters match correctly; only non-ASCII (Unicode) bound parameters fail. Literal Unicode in the SQL text (N'...') is handled fine — the problem is specifically the bound parameter encoding.
Environment
- PHP 8.5.8 (NTS, built 2026-07-01).
- unixODBC 2.3.14 (
libodbc.2.dylib), pdo_odbc built --with-pdo-odbc=unixODBC.
- Microsoft ODBC Driver 18 for SQL Server,
msodbcsql18 18.6.2.1 (libmsodbcsql.18.dylib).
- Microsoft SQL Server 2025 (RTM-CU6, KB5093421) 17.0.4055.5 (X64).
- macOS 26.5.2 (arm64). Not OS-specific — the parameter binding is in
ext/pdo_odbc.
PHP Version
PHP 8.5.8 (cli) (built: Jul 1 2026 03:46:27) (NTS)
Copyright (c) The PHP Group
Built by Homebrew
Zend Engine v4.5.8, Copyright (c) Zend Technologies
with Zend OPcache v8.5.8, Copyright (c), by Zend Technologies
Operating System
macOS 26.5.2 (build 25F84), Apple Silicon / arm64 (Darwin 25.5.0)
Description
When a non-ASCII (e.g. CJK) string is bound as a parameter against an
nvarcharcolumn on SQL Server viapdo_odbc+ Microsoft ODBC Driver 18, the comparison never matches:= ?andLIKE ?both return zero rows, even though the row clearly exists. The same query with the same value works withpdo_sqlsrv.The parameter appears to be bound as a non-Unicode (
SQL_CHAR/ ANSI) string rather thanSQL_WCHAR, so the bytes sent to the server do not match thenvarchar(UTF-16) column data.Reproduction (self-contained, no table required)
Observed vs expected
WHERE v = ?bound'測試中文資料庫'011WHERE v LIKE ?bound'%中文%'011ASCII-only bound parameters match correctly; only non-ASCII (Unicode) bound parameters fail. Literal Unicode in the SQL text (
N'...') is handled fine — the problem is specifically the bound parameter encoding.Environment
libodbc.2.dylib), pdo_odbc built--with-pdo-odbc=unixODBC.msodbcsql1818.6.2.1 (libmsodbcsql.18.dylib).ext/pdo_odbc.PHP Version
Operating System
macOS 26.5.2 (build 25F84), Apple Silicon / arm64 (Darwin 25.5.0)