在准备好的语句中不向列 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
是的,在他更新问题之前,他显示的代码没有bindvalue
或bindParam
以上是关于在准备好的语句中不向列 X 插入值的逻辑 [重复]的主要内容,如果未能解决你的问题,请参考以下文章