我从多个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表添加字段来完成其中一项工作,以便使用输入数组中的所有列。但是,我认为这不是真正解决问题的原因,因为即使在数组的中间,我还有其他人在没有使用所有列的情况下取得成功。
答案 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>";
?>
这假设第一条记录将为每列提供一个条目。我确实有一些不合适的地方,但到目前为止它并没有造成问题,但我可能最终会重写这一点以通过每一行。