【问题标题】:Syntax error with PDO Prepared statementsPDO Prepared 语句的语法错误
【发布时间】:2012-03-27 06:16:50
【问题描述】:

我才刚刚开始使用准备好的语句,我的前几个示例效果很好,但现在我遇到了我不理解的 SQL 语法。我有一个执行 INSERT 的函数,它采用关联数组的参数,其中数组的键是字段,数组的值是要插入的值。例如:

$arr = array("field1" => "value1",
             "field2" => "value2");

$this->insert("table", $arr);

会执行:

INSERT INTO table ('field1', 'field2') VALUES ('value1', 'value2')

但是,当我尝试这样做时,我收到以下错误:

PDOException: SQLSTATE[42000]: 语法错误或访问冲突:1064 您的 SQL 语法有错误;检查手册 对应于您的 MySQL 服务器版本,以便使用正确的语法 ''post_title', 'post_body') VALUES ('Testing!', '1 2 3!')' 附近 第 1 行

这是我的功能:

    /**
     * insert()
     * 
     * Performs an insert query
     * 
     * @param  string $table   The table to be inserted into
     * @param  array  $fields  An associative array of the fields to be inserted
     *                         and their respective values
     * @return void
     *
     */
    function insert($table, $fields) {
        if (empty($table) || empty($fields)) {
            trigger_error('insert(): one or more missing parameters', E_USER_ERROR);
        }

        if (!is_array($fields)) {
            trigger_error('insert(): second parameter expected to be array', E_USER_ERROR);
        }

        for ($i = 0; $i < count($fields); $i++) {
            $mark[] = "?";
        }
    //(?, ?, ...)
    $mark = "(" . implode(", ", $mark) . ")";

    $bind = array_merge(array_keys($fields), array_values($fields));

    //INSERT INTO table (?, ?, ...) VALUES (?, ?, ...)
    $query = 'INSERT INTO '.$table.' '.$mark.' VALUES '.$mark;

    //Prepare and execute
    $stmt = $this->connection->prepare($query);
    var_dump($stmt);
    var_dump($bind);
    $stmt->execute($bind);
}

我是这样称呼它的:

$this->insert('post', array("post_title"=>"Testing!", "post_body"=>"1 2 3!"));

最后的两个 var_dump() 导致:

 object(PDOStatement)[7]
 public 'queryString' => string 'INSERT INTO post (?, ?) VALUES (?, ?)' (length=37)

array
  0 => string 'post_title' (length=10)
  1 => string 'post_body' (length=9)
  2 => string 'Testing!' (length=8)
  3 => string '1 2 3!' (length=6)

我可能错了,但据我了解,没有办法检查发送到服务器的实际查询,所以老实说我不知道​​ SQL 语法的来源。如果有人能指出可能出了什么问题,我将不胜感激。

【问题讨论】:

  • 查询中的表名在哪里?
  • 不能像这样指定字段名称。显式字段名不是字符串或整数,它们是标识符。如果您真的确定列名,第一个$mark 可能是implode(',', array_keys($fields);。我仍然会将这些字段名列入白名单...
  • 另外:请记住 PDO emulates 在特定条件下准备/声明,除非另有说明。

标签: php pdo prepared-statement


【解决方案1】:

您不能绑定标识符。所有志愿 PDO 布道者都不知道的事情。

您必须使用 ol'good 查询构建来添加标识符。

将它们列入白名单并从该列表中创建字段名称子句

请参阅Insert/update helper function using PDO 了解完整的实现。

【讨论】:

  • 你说得对,我刚刚更换了 ?用实际的字段名称标记,它现在可以工作了。我现在需要记住这一点!
【解决方案2】:

字段名称应该用勾号 (``) 而非引号 ('') 括起来。应该是

INSERT INTO (`field1`, `field2`) VALUES ('value1', 'value2')

【讨论】:

    【解决方案3】:

    在您的 SQL 查询中:

    INSERT INTO ('field1', 'field2') VALUES ('value1', 'value2')
    

    您忘记了表名:

    INSERT INTO table('field1', 'field2') VALUES ('value1', 'value2');
    

    【讨论】:

    • 对不起,这是一个错字,在底部的 var_dump 中你应该看到我确实包含了表名。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-10-20
    • 2018-11-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多