【问题标题】:PDO::bindParam/bindValue creates the wrong parameter typePDO::bindParam/bindValue 创建错误的参数类型
【发布时间】:2023-03-28 08:40:01
【问题描述】:

我有一个带有一些整数参数的存储过程:

CREATE PROCEDURE [dbo].[redacted_name]
    @CustomerID int , 
    @ContactPersonID int,
    @ChangeContactPersonId int = null,
    @Name varchar(50)  = NULL
    -- snip
AS
BEGIN
  -- snip
END

我正在使用下面的代码来调用这个存储过程:

$db = $this->db();
$statement = $db->prepare("exec dbo.redacted_name @CustomerId=?,@ContactPersonId=?");

$statement->bindValue(1, 73, PDO::PARAM_INT);
$statement->bindValue(2, 42, PDO::PARAM_INT);
$statement->execute();
//snip

生成以下 SQL,从分析器中获取:

declare @p1 int
exec sp_prepexec @p1 output,N'@P1 TEXT,@P2 TEXT',N'exec dbo.redacted_name  @customerId=@P1,@contactPersonId=@P2','73','42'
select @p1
exec sp_unprepare @p1
go

执行此 SQL,会在 Microsoft Sql Server 11.0.5343 上导致以下错误:

消息 206,级别 16,状态 2,过程 redacted_name,第 0 行
操作数类型冲突:文本与 int 不兼容

这有点道理,因为TEXT != INT 考虑到我特别告诉 PDO 我正在传递一个INT,为什么 PDO 会生成两个 TEXT 变量?我可以做些什么来解决它?

【问题讨论】:

  • 你试过 bindParam() 吗?
  • @Robert 是的。同样的问题。我用bindValue 发布了这个问题,因为这会使代码稍微短一些(不需要变量)。
  • BindParam() 有“驱动程序选项”参数可能会有所帮助
  • @Robert 我错过了那些。经过调查,这是我们目前无法打开的一罐蠕虫。我们在 Linux (RHEL 7) 上托管应用程序,大约需要两个人周的时间才能与数据库进行通信。在我们的例子中,驱动程序选项参数需要特定于 MS 的驱动程序,这些驱动程序适用于 RHEL5 和 RHEL6。不过,我确实觉得这就是解决方案。
  • 很高兴它对您有所帮助,所以也许我会将我的评论作为答案发布,以便可以关闭问题?

标签: php sql-server pdo


【解决方案1】:

我建议您调查 BindParam() 的“驱动程序选项”参数,也许它会有所帮助。

在某些情况下可能是问题所在。

【讨论】:

  • 我还没有找到将 MSSQL 特定选项编译到 Linux 上的 PHP 的方法。 =[
【解决方案2】:

今天我遇到了同样的问题。我得到了类似的东西: 转换规范的字符值无效:206 [Microsoft][ODBC Driver 13 for SQL Server][SQL Server]操作数类型冲突:文本与 int 不兼容。

我在 Linux CentOS 7 上使用带有 PDO 的 PHP 7.0 和 Microsoft ODBC,连接字符串如下:

$pdo = new PDO('odbc:driver=SQL Server Native Client 11.0;server=MyServer;database=MyDB;MARS_Connection=yes', 'user', 'pass');

要解决此问题,需要确切的存储过程参数大小写。

存储过程参数@CustomerID int 用“ID”定义,那么您必须使用@CustomerID = ?而不是@CustomerId = ?...

$statement = $db->prepare("exec dbo.redacted_name @CustomerID=?, @ContactPersonID=?");

看起来驱动程序试图通过使用区分大小写的匹配查看 proc 参数来确定目标类型。

【讨论】:

  • 我已经有一段时间没有问这个问题了,感谢您添加答案!不幸的是,我已经更换了雇主,因此无法验证这是否会解决这个特定项目中的问题。不过,我已将您的回答转达给一位前同事。投赞成票!
猜你喜欢
  • 2014-07-28
  • 2012-02-04
  • 2011-04-13
  • 2014-05-10
  • 2013-08-16
  • 2013-02-15
  • 2014-08-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多