【问题标题】:Warning: PDO::prepare(): SQLSTATE[42000]: Syntax error or access violation: 1064 when update警告:PDO::prepare(): SQLSTATE[42000]: 语法错误或访问冲突:更新时出现 1064
【发布时间】:2018-10-09 18:48:12
【问题描述】:

我想更新几个表如下:

for ($i=0; $i <count($tablesnames); $i++) {

    $update3=$pdo->prepare('UPDATE :surveytable SET `postrecords`=:newrecord WHERE `id`=:id');
//var_dump()here
    $update3->bindValue(':surveytable', $tablesnames[$i],PDO::PARAM_STR);

    $update3->bindValue(':newrecord',$newrecord,PDO::PARAM_STR);

    $update3->bindValue(':id',$id,PDO::PARAM_INT);

    $update3->execute();

}  

检查var_dump结果,$tablesnames[$i]$newrecordstring$idint$update3false
似乎一切正常,但失败了,

警告:PDO::prepare(): SQLSTATE[42000]: 语法错误或访问冲突:1064 您的 SQL 语法有错误;检查与您的 MySQL 服务器版本相对应的手册,以了解在 '? 附近使用的正确语法。设置postrecords=?在哪里id=?

有什么问题?

【问题讨论】:

    标签: pdo


    【解决方案1】:

    (不幸的是)您不能在准备好的语句中为您的表名使用参数。您只能将它们用于 data 文字。所以UPDATE :surveytable是无效的。

    根据manual

    参数标记只能表示完整的数据字面量。两者都不 文字的一部分,也不是关键字,也不是标识符,也不是任意的 查询部分可以使用参数进行绑定。

    当您(完全!!!)信任您的$tablesnames 来源时,请使用

    'UPDATE `' . $tablesnames[i]` . '` SET `postrecords`=:newrecord WHERE `id`=:id'
    

    改为

    【讨论】:

    • 这意味着无法完全避免sql注入,sad!
    • 取决于$tablesnames的来源。当这是用户输入时(例如 POST 数据,甚至是 POST 数据的名称),您绝对应该在查询中使用它之前对其进行验证。例如,使用带有现有表名列表的in_array 或带有仅允许有效表名的正则表达式的preg_match。 (编辑:)虽然我总是尽量避免使用用户输入作为表名(由于这种担忧)。
    猜你喜欢
    • 2018-10-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-12
    • 1970-01-01
    • 2022-01-25
    相关资源
    最近更新 更多