Tra*_*ty3 4 php sql-server pdo sql-server-2008 zend-framework2
我见过类似的错误消息,但大多数都与比较int或float到有关uniqueidenifier,这说明为什么会出现错误。我的错误是这样的:
SQLSTATE[22018]:转换规范的字符值无效:206 [Microsoft][SQL Server Native Client 11.0][SQL Server]操作数类型冲突:文本与唯一标识符不兼容(SQLExecute[206] at /usr/src/php-5.4 .8/ext/pdo_odbc/odbc_stmt.c:254)
我正在构建一个 PHP ZF2 应用程序并尝试使用参数调用用户定义的函数。前四个参数是UNIQUEIDENTIFIER值。最后四个是BIT值。这是我的代码:
public function getCustomerInspectionDocuments($fkCustomer) {
/** @var \Zend\Db\ResultSet\ResultSet $result */
$result = $adapter->query("
SELECT
createUser.FullName AS CreateUser,
udf.CreateTime,
udf.CompleteTime,
modifyUser.FullName AS ModifyUser,
udf.ModifyTime,
udf.Source,
udf.id AS InstanceID
FROM
udfDocumentInstances(
:fkCustomer,
:fkDocumentQueue,
:fkDocumentType,
:fkADUser,
:Completed,
:Deleted,
:LinkByXXX,
:LinkByOwnership
) udf
LEFT JOIN ADUser createUser
ON udf.fkCreateUser = createUser.pkid
LEFT JOIN ADUser deleteUser
ON udf.fkDeleteUser = deleteUser.pkid
LEFT JOIN ADUser modifyUser
ON udf.fkModifyUser = modifyUser.pkid
ORDER BY
ModifyTime DESC
", array(
':fkCustomer' => $fkCustomer,
':fkDocumentQueue' => '57B5829B-3EAE-46FF-8130-8A432176DE2A',
':fkDocumentType' => '7E5D5187-B38A-E211-B52D-0F1256A21434',
':fkADUser' => null,
':Completed' => null,
':Deleted' => 0,
':LinkByXXX' => 0,
':LinkByOwnership' => 0,
));
// do some other stuff and return the records
}
Run Code Online (Sandbox Code Playgroud)
这段代码在针对 SQL Server 2012 执行时完全正常,但是当我将其切换回 2008 时,它会因该错误消息而窒息。我使用相同的驱动程序,所以唯一改变的是服务器。
问题似乎是它针对 UDF 执行的事实以及我通过 PDO 绑定参数的组合。如果我将其更改为简单SELECT查询(来自普通表),它就可以工作。或者,如果我将参数值直接放入查询中,那也可以。但是我需要调用这个UDF,我更喜欢使用参数化查询。
有没有办法准确查看发送到 SQL Server 的内容(即完全组装的查询)?或者它是否有可能作为参数化查询传递给服务器并且是 SQL Server 组装它?
根据我从 SQL Profiler 中发现的内容(感谢 @davek),看起来查询是在 SQL Server 端组装的,并且 PDO 将所有参数作为 传递TEXT,不能隐式转换为UNIQUEIDENTIFIER或BIT。我不确定如何让它CHAR默认通过它们。我也不确定为什么在对普通表使用参数化查询时它不会引起问题。
这是我想出的临时解决方法。这很丑陋,但它现在有效。希望其他人能提出更好的答案。
'...
FROM
dbo.udfDocumentInstances(
CAST(:fkCustomer AS CHAR(36)),
CAST(:fkDocumentQueue AS CHAR(36)),
CAST(:fkDocumentType AS CHAR(36)),
CAST(:fkADUser AS CHAR(36)),
CAST(:Completed AS CHAR(1)),
CAST(:Deleted AS CHAR(1)),
CAST(:LinkByDEA AS CHAR(1)),
CAST(:LinkByOwnership AS CHAR(1))
) udf
...'
Run Code Online (Sandbox Code Playgroud)
所以我将值从TEXTto 转换CHAR,然后 SQL Server 将它们隐式转换为UNIQUEIDENTIFIERor BIT。
如果有人能想出一种方法将它们传递为CHAR而不是TEXT,而不必明确地强制转换每个,请发布您的回复。