在准备好的语句中不向列 X 插入值的逻辑 [重复]

Posted

技术标签:

【中文标题】在准备好的语句中不向列 X 插入值的逻辑 [重复]【英文标题】:Logic to NOT insert a value to column X in a prepared statement [duplicate] 【发布时间】:2020-01-03 17:18:03 【问题描述】:

所以我的表 A 有 X、Y、Z 列。

Y、Z 列的默认值为“多样化”。 当 php 脚本传递用户输入时,输入对象中包含的 3 个值中,Y 列和 Z 列的两个值应该是 NULL。

我想创建一些 PHP 逻辑来评估输入并执行准备好的 PDO 查询,如果相应的输入为空字符串,则 Y 列和 Z 列根本不受影响,因此它们可以由 mysql 设置为 DEFAULT 值。

目前,我的 PDO 准备好的语句如下所示:

  $insertion = $connection->prepare("INSERT INTO products_tbl(product_name, product_manufacturer, product_category)
                                     VALUES(?,?,?)
                                     ");

我尝试构建的控制实际插入的逻辑如下所示:

$insertion->bindValue(1, $productDataInput["productNameInput"]);

  if($productDataInput["productManufacturerInput"] !== NULL)
     $insertion->bindValue(2, $productDataInput["productManufacturerInput"]);
  

  if($productDataInput["productCategoryInput"] !== NULL)
     $insertion->bindValue(3, $productDataInput["productCategoryInput"]);
  

在这里,我收到以下错误:

PDOStatement::execute(): SQLSTATE[HY093]: Invalid parameter number: number of bound variables does not match number of tokens in <b>D:\foundationtests\src\assets\php\addProducts.php</b> on line <b>38</b><br />

所以我猜想这种准备查询的方式需要 3 个值进行插入,但随后只接收 1 个或 2 个值,这是行不通的。 但是,我对准备好的语句很陌生,如果不编写超级冗余代码,我真的不知道如何解决这个问题,我将为每个用例创建自定义的准备好的语句,其中值 2 或 3 或两者都为空。这样的解决方案也不能真正“很好”地扩展,所以我想学习其他更高效、更简洁的方法......^^

例如,我了解到 DEFAULT() 能够触发将默认值设置为列?有没有办法在准备好的 PDO 语句中动态插入 DEFAULT?

【问题讨论】:

【参考方案1】:

您可以使用DEFAULT() 为列插入默认值,并使用IFNULL 将其放入测试中:

$insertion = $connection->prepare("INSERT INTO products_tbl(product_name, product_manufacturer, product_category)
                                   VALUES(?,
                                          IFNULL(?, DEFAULT(product_manufacturer)),
                                          IFNULL(?, DEFAULT(product_category))
                                          )
                                   ");

然后您可以在需要默认值时将NULL 传递给bindValue,即您可以删除if 测试:

$insertion->bindValue(1, $productDataInput["productNameInput"]);
$insertion->bindValue(2, $productDataInput["productManufacturerInput"]);
$insertion->bindValue(3, $productDataInput["productCategoryInput"]);

如果查询中使用的三个值是$productDataInput 中的only 值,您可以使用命名参数进一步简化此操作

$insertion = $connection->prepare("INSERT INTO products_tbl(product_name, product_manufacturer, product_category)
                                   VALUES(:productNameInput,
                                          IFNULL(:productManufacturerInput, DEFAULT(product_manufacturer)),
                                          IFNULL(:productCategoryInput, DEFAULT(product_category))
                                          )
                                   ");
$insertion->execute($productDataInput);

【讨论】:

@GrumpyCrouton 你是对的;只要$productDataInput 中只有这 3 个值,您就可以转到查询的命名参数形式,它会正常工作。 @GrumpyCrouton 我已根据您的建议进行了编辑。谢谢【参考方案2】:

你忘了bindparam

$insertion = $connection->prepare("INSERT INTO products_tbl(product_name, product_manufacturer, product_category)  VALUES(:prod_name , :prod_manufacturer, :prod_category)");

$insertion->bindParam(':prod_name', $var);
$insertion->bindParam(':prod_manufacturer', $var2);
$insertion->bindParam(':prod_category', $var3);
$insertion->->execute();

现在只需将 $var, var2, var3 更改为您想要的 vars

【讨论】:

OP 说有时查询不应该收到 3 个值,还是我误读了? 他更新了我会再看的问题 如果你bindValue,你不必bindParam 是的,在他更新问题之前,他显示的代码没有bindvaluebindParam

以上是关于在准备好的语句中不向列 X 插入值的逻辑 [重复]的主要内容,如果未能解决你的问题,请参考以下文章

使用 PDO 准备好的语句插入致命错误 [重复]

如何为java准备好的语句插入使用表名变量[重复]

如何在准备好的语句php中的不同行中插入多条记录

如何确定从我的 html 表单获取的输入值的数据类型,以便我可以使用它们在准备好的语句中绑定参数

查询正常工作,但在准备好的语句中不工作

为啥准备好的语句在java中不起作用?