php mysqli在准备好的语句中重复字段
Posted
技术标签:
【中文标题】php mysqli在准备好的语句中重复字段【英文标题】:php mysqli repeated fields in prepared statement 【发布时间】:2017-11-08 07:36:58 【问题描述】:我需要将现有项目从 mysql 转换为 mysqli 并使用准备好的语句。
在现有项目中,存在使用重复变量值的查询。 一个这样的例子是:$prev_yr 被使用了 3 次。
$sqlins = "Insert into studentclass (`StudentID`, `ClassID`, `Year`, `Level`, `SNo`, `TermList`, `DateStart`, `DateEnd`)
select StudentID, '$prev_cl', '$prev_yr', '$prev_lvl', '', '123456789', '$prev_yr-01-01', '$prev_yr-12-31' from student Where StudentID in ($ids) ";
还有比这更好的方法吗:
$sqlins = "Insert into studentclass (`StudentID`, `ClassID`, `Year`, `Level`, `SNo`, `TermList`, `DateStart`, `DateEnd`)
select StudentID, '?', '?', '?', '', '123456789', '?-01-01', '?-12-31' from student Where StudentID in (?) ";
$stmt = $mysqli->prepare($sqlins);
$stmt->bind_param("ssssss", $prev_cl,$prev_yr,$prev_lvl,$prev_yr,$prev_yr,$ids);
$stmt->execute();
我想知道是否有一种方法可以为所有 3 次事件绑定一次 $prev_yr。
因为有其他查询可能在一个语句中出现 2 次 $prev_lvl、5 次出现 $prev_yr 等。这个想法是,当多个变量的重复出现在一个语句中变得很多时 - 将它们安排在 bind_param 中会变得非常混乱。
有什么解决办法吗? 谢谢。
【问题讨论】:
我不认为你可以绑定列,因为那是SELECT field
的一部分,而不是 Where 子句。
谢谢 - 在这里学到了一些关于仅在 Where 子句上绑定的知识。
【参考方案1】:
它甚至像那样工作吗?通常你不会在查询中这样做'?-01-01'
。我已经有 4 年没用过 Mysqli 了,因为我现在每天都用 PDO。但据我所知,当你发送它以准备它时,?
会在字符串中出现。
我会拆分它,实际上没有必要进行选择,因为唯一选择的是您已经拥有的学生 ID。简单的
$insert = $mysqli->prepare("Insert into studentclass (`StudentID`, `ClassID`, `Year`, `Level`, `SNo`, `TermList`, `DateStart`, `DateEnd`)VALUES(?, ?, ?, ?, ?, ?, ?, ?)");
foreach( $ids AS $id )
$stmt->bind_param("issssiss", $id, $prev_cl,$prev_yr,$prev_lvl,'', '123456789', $prev_yr.'-01-01',$prev_yr.'-12-31');
$stmt->execute();
我无法测试它,所以希望我把所有东西都放在了正确的地方。
正如我所说,我认为您不能绑定到查询的 Fields
部分,当然也不能绑定到部分字符串中,除了它会进行不需要的选择。只需确保在循环之前准备插入。
只是为了明确 select 实际从数据库中获取的唯一内容就是这个
select StudentID ... from student Where StudentID in (?)
其余的被添加为“假”列,我不知道它的术语。很难阅读原始查询..
【讨论】:
为了您的出色回答,我删除了危险部分。 很公平。对于没有经验的开发人员来说很危险,即使我知道数据是干净的,我个人也会避免它作为最佳实践。 感谢您的建议。对我很有见地,一个没有经验的 mysqli 用户。嗯...看起来我可能需要进入 PDO 方式,因为它们有像 :classx 这样的变量来进行绑定。【参考方案2】:我想知道是否有一种方法可以为所有 3 次事件绑定一次 $prev_yr。
没有。
此外,无论如何它都不会以这种方式工作,因为您不能只绑定您选择的任意查询部分。您只能绑定完整的数据文字。意味着而不是 '?-01-01' 它应该只是 ?,而在你的 php 代码中你应该这样做
$dateStart = "$prev_yr-01-01";
然后将这个变量绑定为整个值。所以不会有更多的重复变量。
【讨论】:
谢谢。这很有见地。如果我要进入 PDO,也许另一个选项可以是 concat(?,'-01-01') 或 concat(:year,'-01-01')? 当然你可以在 SQL 中使用 concat() ,但对我来说它太长了。我打算添加一个关于 PDO 的注释,鼓励你使用它。这对解决这个问题没有帮助,但会让你的代码更加合理。以上是关于php mysqli在准备好的语句中重复字段的主要内容,如果未能解决你的问题,请参考以下文章
如何在mysqli准备好的语句中使用SQL LIKE子句[重复]
什么时候在 PHP Mysqli 中使用准备好的语句? - 用户表单搜索输入与选择查询