在SQL Server上使用PDO时,为什么不能按列别名进行排序?

soa*_*gem 6 php sql sql-server pdo prepared-statement

注意:以下示例中的唯一区别是ORDER BY子句.

好代码:

$sql = 'SELECT [date], ? AS [name] 
FROM [transactions] 
WHERE [category_id] = 10 
GROUP BY [date] 
ORDER BY [date] ASC';

$stmt = $db->prepare($sql);
$stmt->bindValue(1, 'Test', PDO::PARAM_STR);
$stmt->execute();
$data = $stmt->fetchAll();
//returns rows in $data
Run Code Online (Sandbox Code Playgroud)

不好的代码:

$sql = 'SELECT [date], ? AS [name] 
FROM [transactions] 
WHERE [category_id] = 10 
GROUP BY [date] 
ORDER BY [date] ASC, [name] ASC';

$stmt = $db->prepare($sql);
$stmt->bindValue(1, 'Test', PDO::PARAM_STR);
$stmt->execute();
$data = $stmt->fetchAll();
//returns an empty array
Run Code Online (Sandbox Code Playgroud)

为什么我的第二段代码不起作用?如果我直接运行此查询的任一版本(在SQL Management Studio中),它可以以任何方式工作.如果我摆脱PHP中的问号并将值硬编码到查询中(而不是绑定它),那也是有效的!这里发生了什么?

更新:这是一个示例PHP脚本,可以更好地说明问题:http://snipt.org/ALhd1.在这个链接的示例代码中,我包含了5个"测试".测试#1,2和4都返回结果,而测试#3和5则没有并且应该说明问题.

Joa*_*son 1

我已经成功地使用 PHP 5.4 和 SQL Server 2012 重现了该问题。

问题似乎出在 PDO 的 ODBC 驱动程序上。使用两个驱动程序的成功测试给出了相同的结果,但下面使用 test3 作为示例。

使用 Microsoft (3.0) 的本机 SQL Server PHP 驱动程序会给出正确的结果;

$db = new PDO('sqlsrv:server=.\\SQLEXPRESS');

array(3) { [0]=> string(5) "00000" [1]=> NULL [2]=> NULL }
array(1) { [0]=> array(4) {
    ["date"]=> string(23) "2013-07-23 10:34:24.497"
    [0]=>      string(23) "2013-07-23 10:34:24.497"
    ["name"]=> string(4) "Test"
    [1]=>      string(4) "Test"
  }
}
Run Code Online (Sandbox Code Playgroud)

...使用 ODBC 运行完全相同的代码会给出确切的失败结果;

$db = new PDO('odbc:driver={SQL Server Native Client 11.0};server=.\SQLEXPRESS;Trusted_Connection=yes');

array(4) { [0]=>string(5) "00000" [1]=> int(0)  
           [2]=> string(24) " ((null)[0] at (null):0)" [3]=> string(0) "" }
array(0) { }
Run Code Online (Sandbox Code Playgroud)

换句话说,这不是 PDO 本身或 SQL Server 中的限制,而是 ODBC 驱动程序中的限制/错误。