[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)
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.