当前位置: 首页 > 知识库问答 >
问题:

MySQL PDO名称-值准备语句仅使用最后一个参数

甘永春
2023-03-14

如标题所示,我将MySQL PDO与一个预准备语句结合使用,在执行时,我将一个值(最后提供的值)推入所有字段。

表看起来是这样的:

    < li>id (int -自动递增) < li>a_id (int) < li>b_id (int)

INSERT看起来像这样:

INSERT INTO my_table(a_id, b_id) 
VALUES (:a_id, :b_id)

要插入的代码如下所示...

$stmt = $conn->prepare($sql);

foreach($params as $k => $v) {
    $stmt->bindParam(
        $k,
        $v
    );
}

$stmt->execute();

语句成功插入一个值(确认$conn存在、活动和打开,语句已设置并绑定参数)。

我已经通过在foreach内部进行调试确认了这些值,其中我获得了“:a _ id”=

不过,我的记录显示为({new_id},9999,9999)。

这意味着它看到并使用":b_id"=

我认为下划线可能是一个问题(但显然过去有几个人检查过源代码,认为下划线是好的...虽然连字符不是)。

我没有重用参数(我的理解是每个预处理语句只允许使用一次)...

我是否遗漏了一些命名参数问题?因为它基本上是-

我试图在使用无脂肪框架时解决基于ORM的数据访问的速度问题,但我不认为存在干扰。

作为参考,这是在PHP 5.5.8/Windows/IIS下运行的。

编辑:*

我可以确定移动到位置参数也是一样的。

INSERT INTO my_table(a_id, b_id) 
VALUES (?, ?)

代码更改为...

$stmt = $conn->prepare($sql);

$i = 1;
foreach($params as $value) {
    $stmt->bindParam(
        $i,
        $value
    );
    $i++;
}

$stmt->execute();

阐明$params数组是如何设置的...事情被传递给这段代码(它是抽象数据库处理程序的核心),数组是手工构建的...

即。

$results = \XX\DB::do_cmd(
    $db, 
    self::SQL_INSERT, 
    array(
        ':a_id' => intval($this->a_id),
        ':b_id' => intval($this->b_id),
    )
);

还有({new_id},9999,9999)...

注意:为了消除混淆,除了去一个基于位置的通行证,我还硬编码了值,看看我会得到什么...

$results = \XX\DB::do_cmd(
    $db, 
    self::SQL_INSERT, 
    array(
        1,
        1234,
    )
);

我的战绩出来了({new_id},1234,1234)。同样的问题,不同的价值观。

我有一种感觉,这里有一个“陷阱”......但我不知道它是什么。

有趣的是,我在INSERT之前根据这两个值(以防止重复)仔细检查表中的现有记录,并且检查正确识别记录在那里...尽管它在数据库中是错误的...这意味着 SELECT 和 INSERT 对参数执行相同的操作(尽管并不奇怪,因为参数处理是相同的)。

编辑2:

更新为已解决的注释。使用。。。

$stmt->execute($params); // scrap the foreach nonsense...

bindValue()而不是bindParam()也是合适的。

注意:我正在从下面的PHP文档(http://php.net/manual/en/pdo.prepared-statements.php)工作,它没有区分bindValue()与bindParam()...

共有2个答案

韩鸿
2023-03-14

变量必须按引用调用:

$stmt = $conn->prepare($sql);

foreach($params as $k => &$v) {
    $stmt->bindParam(
        $k,
        $v
    );
}
$stmt->execute();

请参见此处的第一条用户评论:

http://php.net/manual/en/pdostatement.bindparam.php

龙才俊
2023-03-14

感谢大家的帮助!

我采用了迈克尔的解决方案,但也测试了瑞安的。

即。

更新为已解决的注释。使用。。。

$stmt->execute($params); // scrap the foreach nonsense...

bindValue()而不是bindParam()也是合适的。

根据瑞安的评论,总结一下,我正在推出一个答案。

再次感谢!

 类似资料:
  • 问题内容: 我正在尝试使用准备好的语句来设置表名以从中选择数据,但是执行查询时,我总是收到错误消息。 错误和示例代码如下所示。 有什么想法可能导致这种情况? 问题答案: 表名不能用作参数。它必须是硬编码的。因此,你可以执行以下操作:

  • Im使用具有2000多个参数标记的构建大型数据库调用。 我收到这个错误 我试着搜索API文档和google,但找不到如何配置它。 有没有人知道是否有可能达到这个限度?我知道这将是一个缓慢的数据库调用,但这是好的现在。 从长远来看,这是否会给我带来任何问题?批量运行是否会更好?

  • 问题内容: 这可能吗?例如 如果没有,我应该这样做吗: 还是我需要学习其他技巧? 问题答案: 表名和列名不能用PDO中的参数替换。请参见PHP PDO语句可以接受表名或列名作为参数吗?

  • 问题内容: 使用PDO时,我已经看到很多文章在命名参数前使用冒号(),还有一些不使用冒号的文章。我会尽快不使用冒号,只是因为它的按键少了一点,而且读起来也更容易一点。 这似乎对我来说很好,但是我很好奇在使用冒号时是否缺少一些重要的东西? 例如,这很好用: 与大多数使用此功能的开发人员相对,这也可以: 注意语句参数中的冒号。 我想了解冒号的用途。 问题答案: SQL语句中必须使用冒号,以指示哪些标识

  • 问题内容: 我正在自定义由hibernate生成的插入SQL,并遇到了问题。当Hibernate自己生成查询时,它将数据插入表的前两列,但这会导致数据库错误,因为表的所有四列都是不可为空的。为了正确执行插入,它必须将相同的数据插入到新记录的两列中。这意味着我需要Hibernate将相同的数据绑定到我正在编写的查询(准备好的语句)中的两个不同的参数上。 是否有一些SQL语法可让我以与绑定到绑定语句不

  • 问题内容: 我使用具有2000多个参数标记的大型数据库调用进行构建。 我收到这个错误 我尝试搜索API文档和Google,但是找不到如何配置它。 有谁知道是否有可能提高这个限制?我知道这将是一个缓慢的数据库调用,但是现在还可以。 从长远来看,这还会给我造成任何问题吗,我最好分批运行吗? 问题答案: 接缝处好像停留在2000年。这是驱动程序来源的一部分。 这是一个博客,其中包含有关如何解决该问题的示