php ON DUPLICATE KEY UPDATE 也说 1062: Duplicate entry for key 'PRIMARY'
php ON DUPLICATE KEY UPDATE also says 1062: Duplicate entry for key 'PRIMARY'
有一个数据库在线。该数据库在本地和在线具有相同的模式,超过 25 tables。我正在通过 JSON 文件发送 INSERT 或 UPDATE 记录。 id
是所有 table 的关键字段。 JSON 文件可能包含要插入的新 id
记录和要更新整个在线 table 字段的旧 id
字段。
以下是counters
table在线
+-------+---------+---------------+---------------------+---------------------+------------+
| id | name | description | added_on | last_updated | department |
+-------+---------+---------------+---------------------+---------------------+------------+
| 1 | A | Bill | 2018-02-18 21:48:28 | 2018-02-18 15:08:34 | 1 |
| 2 | B | SAKTHY | 2018-06-21 12:49:30 | 2018-02-18 12:49:40 | 1 |
| 3 | C | | 2018-02-18 21:48:28 | 2018-02-18 21:48:28 | 1 |
+-------+---------+---------------+---------------------+---------------------+------------+
以下数据由JSON文件传递到在线数据库。
[
{
"tableName": "bank_accounts",
"rows": []
},
{
"tableName": "counters",
"rows": [
{
"id": "2",
"name": "B",
"description": "SAKTHY",
"added_on": "2018-06-21T12:49:30",
"last_updated": "2018-02-18T12:49:40",
"department": "1"
},
{
"id": "5",
"name": "E",
"description": "SAKTHY2",
"added_on": "2018-06-21T12:50:21",
"last_updated": "2018-06-21T14:52:18",
"department": "1"
},
{
"id": "6",
"name": "SAKTHY3",
"description": "Sample Friday",
"added_on": "2018-06-22T10:47:18",
"last_updated": "2018-06-22T10:47:18",
"department": "1"
}
]
},
{
"tableName": "customers",
"rows": []
}
]
为了INSERT
或UPDATE
在线数据库的记录,使用了这个php脚本(感谢@Sloan Thrasher,@lovepreet-singh)。
<?php
try
{
$connect = mysqli_connect("localhost", "username", "password", "database");
$query = '';
$table_data = '';
$filename = "sample.json";
$data = file_get_contents($filename);
$array = json_decode($data, true);
foreach($array as $set)
{
$tblName = $set['tableName'];
if(sizeof($set['rows']) > 0)
{
$query = '';
$colList = array();
$valList = array();
// Get list of column names
foreach($set['rows'][0] as $colName => $dataval)
{
$colList[] = "`".$colName."`";
}
$query .= "INSERT INTO `".$tblName."` \n";
$query .= "(".implode(",",$colList).")\nVALUES\n";
// Go through the rows for this table.
foreach($set['rows'] as $idx => $row)
{
$colDataA = array();
// Get the data values for this row.
foreach($row as $colName => $colData)
{
$colDataA[] = "'".$colData."'";
}
$valList[] = "(".implode(",",$colDataA).")";
}
// Add values to the query.
$query .= implode(",\n",$valList)."\n";
// If id column present, add ON DUPLICATE KEY UPDATE clause
if(in_array("id", $colList))
{
$query .= "ON DUPLICATE KEY UPDATE\n\t SET ";
$tmp = array();
foreach($colList as $idx => $colName)
{
//$tmp[] = $colName." = new.".$colName." ";
$tmp[] = $colName." = VALUE(".$colName.") "; // Changed this line to get value from current insert row data
}
$query .= implode(",",$tmp)."\n";
}
else
{
echo "<p><b>`id`</b> column not found. <i>ON DUPLICATE KEY UPDATE</i> clause <b>NOT</b> added.</p>\n";
echo "<p>Columns Found:<pre>".print_r($colList, true)."</pre></p>\n";
}
echo "<p>Insert query:<pre>$query</pre></p>";
$r = mysqli_query($connect, $query);
echo mysqli_errno($connect) . ": " . mysqli_error($connect) . "\n";
echo "<h1>".mysqli_affected_rows($connect). " Rows appended in .$tblName.</h1>";
}
else
{
echo "<p>No rows to insert for .$tblName.</p>";
}
}
}
catch(Exception $e)
{
echo $e->getMessage();
}
?>
但我在浏览器中得到以下 SQL 回显。在这种情况下,在线数据库不会更新或插入新记录。
No rows to insert for .bank_accounts.
`id` column not found. ON DUPLICATE KEY UPDATE clause NOT added.
Columns Found:
Array
(
[0] => `id`
[1] => `name`
[2] => `description`
[3] => `added_on`
[4] => `last_updated`
[5] => `department`
)
Insert query:
INSERT INTO `counters`
(`id`,`name`,`description`,`added_on`,`last_updated`,`department`)
VALUES
('2','B','SAKTHY','2018-06-21T12:49:30','2018-02-18T12:49:40','1'),
('5','E','SAKTHY2','2018-06-21T12:50:21','2018-06-21T14:52:18','1'),
('6','SAKTHY3','Sample Friday','2018-06-22T10:47:18','2018-06-22T10:47:18','1')
1062: Duplicate entry '2' for key 'PRIMARY'
-1 Rows appended in .counters.
No rows to insert for .customers.
尝试替换脚本的这一部分:
if(in_array("id", $colList))
{
$query .= "ON DUPLICATE KEY UPDATE\n\t SET ";
$tmp = array();
foreach($colList as $idx => $colName)
{
//$tmp[] = $colName." = new.".$colName." ";
$tmp[] = $colName." = VALUE(".$colName.") "; // Changed this line to get value from current insert row data
}
$query .= implode(",",$tmp)."\n";
}
else
{
echo "<p><b>`id`</b> column not found. <i>ON DUPLICATE KEY UPDATE</i> clause <b>NOT</b> added.</p>\n";
echo "<p>Columns Found:<pre>".print_r($colList, true)."</pre></p>\n";
}
与 :
$query .= "ON DUPLICATE KEY UPDATE\n\t ";
$tmp = array();
foreach($colList as $idx => $colName)
{
//$tmp[] = $colName." = new.".$colName." ";
$tmp[] = $colName." = VALUES(".$colName.") "; // Changed this line to get value from current insert row data
}
$query .= implode(",",$tmp)."\n";
你的问题是在你的代码中,你有以下内容:
$colList[] = "`".$colName."`";
您正在检查:
if(in_array("id", $colList))
添加到数组时,您在列名周围打上了勾号,您在 in_array
部分没有搜索它。
要么将 $colList
添加更改为:
$colList[] = $colName;
或数组搜索为:
if(in_array("`id`", $colList))
你的问题出在支票上
if(in_array("id", $colList))
改为
if(in_array("`id`", $colList))
也改
$tmp[] = $colName." = VALUE(".$colName.") ";
到
$tmp[] = "{$colName} = {$colName}";
编辑:您将在下面找到我的代码版本。希望这有帮助:
<?php
try
{
$connect = mysqli_connect("localhost", "username", "password", "database");
$filename = "sample.json";
$dataSets = json_decode(file_get_contents($filename), true);
if (is_null($dataSets)) {
throw new Exception(json_last_error_msg());
}
foreach($dataSets as $dataSet)
{
$tblName = $dataSet['tableName'];
$dataSetRows = $dataSet['rows'];
if (!$dataSetRows) {
echo "<p>No rows to insert for . $tblName . </p>";
continue;
}
foreach($dataSetRows as $dataSetRow){
$colList = array_keys($dataSetRow);
$valList = array_values($dataSetRow);
$query = "INSERT INTO {$tblName} (" . implode(",", $colList) . ") VALUES (\"" . implode('","', $valList) . '")';
if(in_array("id", $colList)) {
$query .= " ON DUPLICATE KEY UPDATE ";
array_walk($dataSetRow, function($val, $col) use (&$query){
if($col !=='id') {
$query .= "{$col} = \"{$val}\",";
};
});
}
$query = rtrim($query, ',');
echo "<p>Insert query:<pre>$query</pre></p>";
mysqli_query($connect, $query);
echo mysqli_errno($connect) . ": " . mysqli_error($connect) . "\n";
echo "<h1>".mysqli_affected_rows($connect). " Rows appended in .$tblName.</h1>";
}
}
} catch(Exception $e) {
echo $e->getMessage();
}
有一个数据库在线。该数据库在本地和在线具有相同的模式,超过 25 tables。我正在通过 JSON 文件发送 INSERT 或 UPDATE 记录。 id
是所有 table 的关键字段。 JSON 文件可能包含要插入的新 id
记录和要更新整个在线 table 字段的旧 id
字段。
以下是counters
table在线
+-------+---------+---------------+---------------------+---------------------+------------+
| id | name | description | added_on | last_updated | department |
+-------+---------+---------------+---------------------+---------------------+------------+
| 1 | A | Bill | 2018-02-18 21:48:28 | 2018-02-18 15:08:34 | 1 |
| 2 | B | SAKTHY | 2018-06-21 12:49:30 | 2018-02-18 12:49:40 | 1 |
| 3 | C | | 2018-02-18 21:48:28 | 2018-02-18 21:48:28 | 1 |
+-------+---------+---------------+---------------------+---------------------+------------+
以下数据由JSON文件传递到在线数据库。
[
{
"tableName": "bank_accounts",
"rows": []
},
{
"tableName": "counters",
"rows": [
{
"id": "2",
"name": "B",
"description": "SAKTHY",
"added_on": "2018-06-21T12:49:30",
"last_updated": "2018-02-18T12:49:40",
"department": "1"
},
{
"id": "5",
"name": "E",
"description": "SAKTHY2",
"added_on": "2018-06-21T12:50:21",
"last_updated": "2018-06-21T14:52:18",
"department": "1"
},
{
"id": "6",
"name": "SAKTHY3",
"description": "Sample Friday",
"added_on": "2018-06-22T10:47:18",
"last_updated": "2018-06-22T10:47:18",
"department": "1"
}
]
},
{
"tableName": "customers",
"rows": []
}
]
为了INSERT
或UPDATE
在线数据库的记录,使用了这个php脚本(感谢@Sloan Thrasher,@lovepreet-singh)。
<?php
try
{
$connect = mysqli_connect("localhost", "username", "password", "database");
$query = '';
$table_data = '';
$filename = "sample.json";
$data = file_get_contents($filename);
$array = json_decode($data, true);
foreach($array as $set)
{
$tblName = $set['tableName'];
if(sizeof($set['rows']) > 0)
{
$query = '';
$colList = array();
$valList = array();
// Get list of column names
foreach($set['rows'][0] as $colName => $dataval)
{
$colList[] = "`".$colName."`";
}
$query .= "INSERT INTO `".$tblName."` \n";
$query .= "(".implode(",",$colList).")\nVALUES\n";
// Go through the rows for this table.
foreach($set['rows'] as $idx => $row)
{
$colDataA = array();
// Get the data values for this row.
foreach($row as $colName => $colData)
{
$colDataA[] = "'".$colData."'";
}
$valList[] = "(".implode(",",$colDataA).")";
}
// Add values to the query.
$query .= implode(",\n",$valList)."\n";
// If id column present, add ON DUPLICATE KEY UPDATE clause
if(in_array("id", $colList))
{
$query .= "ON DUPLICATE KEY UPDATE\n\t SET ";
$tmp = array();
foreach($colList as $idx => $colName)
{
//$tmp[] = $colName." = new.".$colName." ";
$tmp[] = $colName." = VALUE(".$colName.") "; // Changed this line to get value from current insert row data
}
$query .= implode(",",$tmp)."\n";
}
else
{
echo "<p><b>`id`</b> column not found. <i>ON DUPLICATE KEY UPDATE</i> clause <b>NOT</b> added.</p>\n";
echo "<p>Columns Found:<pre>".print_r($colList, true)."</pre></p>\n";
}
echo "<p>Insert query:<pre>$query</pre></p>";
$r = mysqli_query($connect, $query);
echo mysqli_errno($connect) . ": " . mysqli_error($connect) . "\n";
echo "<h1>".mysqli_affected_rows($connect). " Rows appended in .$tblName.</h1>";
}
else
{
echo "<p>No rows to insert for .$tblName.</p>";
}
}
}
catch(Exception $e)
{
echo $e->getMessage();
}
?>
但我在浏览器中得到以下 SQL 回显。在这种情况下,在线数据库不会更新或插入新记录。
No rows to insert for .bank_accounts.
`id` column not found. ON DUPLICATE KEY UPDATE clause NOT added.
Columns Found:
Array
(
[0] => `id`
[1] => `name`
[2] => `description`
[3] => `added_on`
[4] => `last_updated`
[5] => `department`
)
Insert query:
INSERT INTO `counters`
(`id`,`name`,`description`,`added_on`,`last_updated`,`department`)
VALUES
('2','B','SAKTHY','2018-06-21T12:49:30','2018-02-18T12:49:40','1'),
('5','E','SAKTHY2','2018-06-21T12:50:21','2018-06-21T14:52:18','1'),
('6','SAKTHY3','Sample Friday','2018-06-22T10:47:18','2018-06-22T10:47:18','1')
1062: Duplicate entry '2' for key 'PRIMARY'
-1 Rows appended in .counters.
No rows to insert for .customers.
尝试替换脚本的这一部分:
if(in_array("id", $colList))
{
$query .= "ON DUPLICATE KEY UPDATE\n\t SET ";
$tmp = array();
foreach($colList as $idx => $colName)
{
//$tmp[] = $colName." = new.".$colName." ";
$tmp[] = $colName." = VALUE(".$colName.") "; // Changed this line to get value from current insert row data
}
$query .= implode(",",$tmp)."\n";
}
else
{
echo "<p><b>`id`</b> column not found. <i>ON DUPLICATE KEY UPDATE</i> clause <b>NOT</b> added.</p>\n";
echo "<p>Columns Found:<pre>".print_r($colList, true)."</pre></p>\n";
}
与 :
$query .= "ON DUPLICATE KEY UPDATE\n\t ";
$tmp = array();
foreach($colList as $idx => $colName)
{
//$tmp[] = $colName." = new.".$colName." ";
$tmp[] = $colName." = VALUES(".$colName.") "; // Changed this line to get value from current insert row data
}
$query .= implode(",",$tmp)."\n";
你的问题是在你的代码中,你有以下内容:
$colList[] = "`".$colName."`";
您正在检查:
if(in_array("id", $colList))
添加到数组时,您在列名周围打上了勾号,您在 in_array
部分没有搜索它。
要么将 $colList
添加更改为:
$colList[] = $colName;
或数组搜索为:
if(in_array("`id`", $colList))
你的问题出在支票上
if(in_array("id", $colList))
改为
if(in_array("`id`", $colList))
也改
$tmp[] = $colName." = VALUE(".$colName.") ";
到
$tmp[] = "{$colName} = {$colName}";
编辑:您将在下面找到我的代码版本。希望这有帮助:
<?php
try
{
$connect = mysqli_connect("localhost", "username", "password", "database");
$filename = "sample.json";
$dataSets = json_decode(file_get_contents($filename), true);
if (is_null($dataSets)) {
throw new Exception(json_last_error_msg());
}
foreach($dataSets as $dataSet)
{
$tblName = $dataSet['tableName'];
$dataSetRows = $dataSet['rows'];
if (!$dataSetRows) {
echo "<p>No rows to insert for . $tblName . </p>";
continue;
}
foreach($dataSetRows as $dataSetRow){
$colList = array_keys($dataSetRow);
$valList = array_values($dataSetRow);
$query = "INSERT INTO {$tblName} (" . implode(",", $colList) . ") VALUES (\"" . implode('","', $valList) . '")';
if(in_array("id", $colList)) {
$query .= " ON DUPLICATE KEY UPDATE ";
array_walk($dataSetRow, function($val, $col) use (&$query){
if($col !=='id') {
$query .= "{$col} = \"{$val}\",";
};
});
}
$query = rtrim($query, ',');
echo "<p>Insert query:<pre>$query</pre></p>";
mysqli_query($connect, $query);
echo mysqli_errno($connect) . ": " . mysqli_error($connect) . "\n";
echo "<h1>".mysqli_affected_rows($connect). " Rows appended in .$tblName.</h1>";
}
}
} catch(Exception $e) {
echo $e->getMessage();
}