HY093在PDO

时间:2018-02-01 05:05:05

标签: php mysql pdo

我从多个API请求中获取数据并将每个请求存储在单独的MySQL表中。对于每个请求,我都有一个关联的表,其字段名称与JSON API响应相匹配。因为我没有使用API​​中的所有字段,所以我在MySQL表中找到字段并使用它来创建带有PDO的预准备语句,然后将结果数组输入到执行中。这是接受语句和结果数组的函数:

function insert_array($sql,$args)
{
    $this->connect();
    $q = $this->con->prepare($sql);
    foreach($args as $record) {
        $q ->execute($record);
        echo "<pre>";var_dump($record);echo "</pre>";
        $arr = $q->errorInfo();
        print_r($arr);
    }
    $this->disconnect();
    return $q;
}

foreach循环中的最后三行仅用于调试。

这对我的第一次请求工作正常,但没有插入记录,我收到HY093,其他人。

对于有效的语句,预准备语句($ sql)以

形式出现
INSERT INTO fs_dynamicagents (agent_id, firstname, lastname) VALUES (:agent_id, :firstname, :lastname) ON DUPLICATE KEY UPDATE firstname=:firstname, lastname=:lastname

我首先找到了唯一的字段,这就是为什么agent_id不在更新语句中。这成功插入,即使我没有使用所有字段。这是var_dump和errorInfo的输出:

array(4) {
  ["agent_id"]=>
  string(3) "002"
  ["firstname"]=>
  string(9) "Bill"
  ["lastname"]=>
  string(5) "Murray"
  ["password"]=>
  string(4) "1212"
}
Array ( [0] => 00000 [1] => [2] => )

现在这是一个不起作用的例子:

INSERT INTO fs_queue (name, record) VALUES (:name, :record) ON DUPLICATE KEY UPDATE record=:record

第一个API记录的一部分:

array(79) {
  ["name"]=>
  string(7) "Choice1"
  ["fc_name"]=>
  string(7) "Choice1"
  ["friendlyname"]=>
  string(7) "Choice1"
  ["record"]=>
  string(1) "1"
  ["agent_announcement_file"]=>
  string(0) ""
  ["play_agent_announcement_file"]=>
  string(1) "0"
  ["incoming_call_script"]=>
  string(0) ""
  ["caller_agent_match"]=>
  string(1) "0"
  ["survey_id"]=>
  NULL
}

Array ( [0] => HY093 [1] => [2] => )

您可以看到我没有包含所有79个字段,但我尝试在标签中至少包含“name”字段,以及空字符串和空值。除了“名字”和“记录”之外别无其他,所以我不认为这是一个问题。

我在网上找到的这个错误代码的每个实例都是由于类型(或区分大小写)造成的。我已经尝试将“record”定义为int和varchar。

好吧,我曾希望打出这个问题的过程会让问题暴露给我,但没有这样的运气。如果晚上的睡眠没有帮助,我会喜欢听到的想法。

编辑:我尝试的其他内容是删除ON DUPLICATE UPDATE部分(并清空表以便不会有任何重复),以便每个参数仅绑定一次。听起来这是几年前修复过的一个错误,但即便没有,我也会收到同样的错误。

Edit2:嗯,更奇怪的是,删除ON DUPLICATE UPDATE导致我以前工作的一些语句失败并出现同样的错误。并非所有这些,当然,那些因为那个原因而没有失败的人如果遇到重复就会失败。

Edit3:我尝试过的其他方法是删除update语句的绑定,并将其更改为

INSERT INTO fs_queue (name, record) VALUES (:name, :record) ON DUPLICATE KEY UPDATE record= VALUES(record)

我认为不会解决这个问题,因为它在第一种方式上取得了成功,而实际上它仍然失败了。

Edit4:我能够通过向MySQL表添加字段来完成其中一项工作,以便使用输入数组中的所有列。但是,我认为这不是真正解决问题的原因,因为即使在数组的中间,我还有其他人在没有使用所有列的情况下取得成功。

1 个答案:

答案 0 :(得分:0)

好的,我明白了。首先,我根本没有设置ATTR_EMULATE_PREPARES,这意味着它将默认为数据库准备引擎,除非需要PDO引擎。由于 MySQL 无法重复使用占位符,因此它使用的是PDO引擎。将其设置为false将强制MySQL引擎,并且所有请求都将失败。

因此,PDO引擎可以重复使用占位符,但是不管怎样,它都不是很好找到值。即使试图找到3列中的2列,它有时也会失败。因此,不要让PDO对其进行排序,而是在发送它之前将其丢弃所有我想要插入的内容。

我正在使用一个函数来删除我找到的here

<?php

function delete_col(&$array, $key) {
    return array_walk($array, function (&$v) use ($key) {
        unset($v[$key]);
    });
}

$table_fields = array("id","fruit");

$insert_data = array(
    array( 
        "id" => "1",
        "fruit" => "Apple",
        "color" => "Red"
    ),array( 
        "id" => "2",
        "fruit" => "Apple",
        "color" => "Green"
    ),array( 
        "id" => "3",
        "fruit" => "Pear",
        "color" => "Green"
    )
);

foreach($insert_data[0] as $key=>$value) {
    if(!in_array($key, $table_fields)) {
        delete_col($insert_data, $key);
    }
}
echo "<pre>";
print_r($insert_data);
echo "</pre>";

?>

这假设第一条记录将为每列提供一个条目。我确实有一些不合适的地方,但到目前为止它并没有造成问题,但我可能最终会重写这一点以通过每一行。