注意:以下示例中唯一的区别是 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
错误代码:
$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
为什么我的第二个代码块不起作用?如果我直接运行此查询的任一版本(在SQL Management Studio中),它都可以正常工作。如果我摆脱PHP中的问号并将值硬编码到查询中(而不是绑定它),那也是有效的!这是怎么回事?
更新:以下示例PHP示例更好地说明了问题:http://snipt.org/ALhd1。在这个链接的示例代码中,我包含了5个“测试”。测试#1,2和4都返回结果,而测试#3和5则没有并且应该说明问题。
答案 0 :(得分: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"
}
}
...使用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) { }
换句话说,它不是PDO本身或SQL Server中的限制,它是ODBC驱动程序中的限制/错误。
答案 1 :(得分:0)
我试图重现这个问题,但我不能。但是,我怀疑“准备”是在order by
中识别一个常数,这是一个错误。您可以使用显式常量轻松查看错误:
select *
from information_schema.tables t
order by 'a'
失败并显示错误:
Msg 408, Level 16, State 1, Line 3
A constant expression was encountered in the ORDER BY list, position 1.
那说,这有效:
select *, 'a' as name
from information_schema.tables t
order by name;
以下是解决问题的建议。尝试使用子查询:
SELECT [date], (select ?) AS [name]
FROM [transactions]
WHERE [category_id] = 10
GROUP BY [date]
ORDER BY [date] ASC, [name] ASC;
select
的附加级别应该说服某些东西,某个地方你的值不是常数(并且仍然为它分配一个值)。