[php-src] Issue #23444: ext/pdo_odbc: a bound Unicode (nvarchar) string parameter never matches — WHERE col = ? / WHERE col LIKE ? with a non-ASCII value returns no rows (works correctly with pdo_sqlsrv)
[email protected] (chep6915)
| Newsgroups | php.bugs |
|---|---|
| Message-ID | <[email protected]> |
Issue: https://github.com/php/php-src/issues/23444
Author: chep6915
### 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
<?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
```plain
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)