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 中使用准备好的语句? - 用户表单搜索输入与选择查询

php mysqi bind_param 变量数与准备好的语句中的参数数不匹配[重复]

如何使用索引号将数据发送到mysqli(准备好的语句)

带有变量的Mysqli准备好的语句列[重复]

使用 mysqli 和准备好的语句时命令不同步 [重复]