将空字符串绑定到 pdo 准备好的查询时 HY104 Sql server 错误

Posted

技术标签:

【中文标题】将空字符串绑定到 pdo 准备好的查询时 HY104 Sql server 错误【英文标题】:HY104 Sql server error when binding an empty string to a pdo prepared query 【发布时间】:2012-09-12 19:12:59 【问题描述】:

我应该将应用程序从 mssql 函数移动到 PDO。一切都运行顺利,直到我发现自己似乎无法解决一个不错的小错误。

这是我准备好的请求:

$req_action="INSERT INTO [".DB_SCHEMA."].[dbo].[".ACTION_TABLE."] 
([ID_CONTACT]
,[ID_ADN]
,[TYPE_ACTION]
,[MOTIF_ENTRANT]
,[COMMENTAIRES_APPEL]
,[CODE_CAMPAGNE]
,[EMAIL]
,[SUJET]
,[STATUT_EMAILING]
,[DATE_ENVOI]
,[DELAI_OUVERTURE]
,[MAIL_CLIENT]
,[DATE_OUVERTURE]
,[LIEN_CLIQUE]
,[DELAI_CLIC]
,[DATE_CLIC]
,[DATE_ACTION]
,[USER_ID]
,[LOGIN]
,[DATE_CHARGEMENT]
)
VALUES
(''
,''
,'e-mailing'
,''
,''
,''
,:email
,:sujet
,:statut
,convert(datetime,:date_envoi,103)
,:delai
,:mail
,convert(datetime,:date_ouverture,103)
,:lien_clic
,:delai_clic
,convert(datetime,:date_clic,103)
,convert(datetime,:date_action,103)
,'1'
,'AUTO'
,getdate()
)";

还有我的绑定:

$prep_req_action->bindValue(":email",$email,PDO::PARAM_STR);
$prep_req_action->bindValue(":sujet",$sujet,PDO::PARAM_STR);
$prep_req_action->bindValue(":statut",$statut_emailing,PDO::PARAM_STR);
$prep_req_action->bindValue(":date_envoi",$sql_date_envoi,PDO::PARAM_STR);
$prep_req_action->bindValue(":delai",$delai_ouverture,PDO::PARAM_STR);
$prep_req_action->bindValue(":mail",$mail_client,PDO::PARAM_STR);
$prep_req_action->bindValue(":date_ouverture",$sql_date_ouverture,PDO::PARAM_STR);
$prep_req_action->bindValue(":lien_clic",$lien_clique,PDO::PARAM_STR);
$prep_req_action->bindValue(":delai_clic",$delai_clic,PDO::PARAM_STR);
$prep_req_action->bindValue(":date_clic",$sql_date_clic,PDO::PARAM_STR);
$prep_req_action->bindValue(":date_action",$sql_date_action,PDO::PARAM_STR);

问题是每当我的 php 变量之一恰好是空字符串(来自自动 csv 文件,它实际上经常发生)SQL 服务器返回错误 HY104(无效精度)。

我的所有字段都是 NULL 授权的,因此我将 PDO::ATTR_ORACLE_NULLS 属性切换为 PDO::NULL_EMPTY_STRING 以将空字符串转换为 NULL,但行为完全相同。

我发现的唯一解决方法是在绑定之前测试我的变量是否为空以将其设置为 php null:

$lien_clique = (empty($lien_clique)) ? null : $lien_clique;

这确实有效,但我觉得 NULL_EMPTY_STRING 的 PDO 属性应该为我做这件事,而且我有大量的查询要更新,我不想用这个 tweek 保护一切。

有人知道问题的原因和解决方法吗?

仅供参考:Linux 上的 PHP 5.3.1、pdo_sqlsrv 3.0 和 SQL Server 2000。

【问题讨论】:

我知道这是旧的,但你有没有试过这样做: $prep_req_action->bindValue(":email",trim($email),PDO::PARAM_STR);以确保没有空白字符混淆事物。 您好,感谢您的建议。不幸的是,我没有想到在绑定之前修剪变量。我实际上用我提到的调整保护了我所有的绑定。但是当我将我的应用程序从开发平台转移到生产平台时,问题就消失了。我没有时间找出这两个环境之间的配置差异。我敢打赌,我的开发环境设置会出现版本兼容性故障。 【参考方案1】:

听起来您在字符串列上设置了大小,并且您的数据库可能要求在插入时指定它。

尝试使用...

$stmt->bindValue(":field",$value,PDO::PARAM_STR,$length);

在给出错误的字段上,其中 $length 是数据库中指定的字段大小。这样做很痛苦,但我记得不久前在 ODBC 驱动程序中遇到过这个问题。

【讨论】:

以上是关于将空字符串绑定到 pdo 准备好的查询时 HY104 Sql server 错误的主要内容,如果未能解决你的问题,请参考以下文章

从 PDO 准备好的语句中获取原始 SQL 查询字符串

从 PDO 准备好的语句中获取原始 SQL 查询字符串

了解 PDO 准备好的语句和绑定参数

带有位域的 PDO 准备好的语句

从 PDO 准备语句中检索(或模拟)完整查询

在 PHP 中到处使用准备好的语句? (PDO)