[英]Why doesn't the count match the value for the SQL query?
我不能很好地解释我的问题,但是这里的代码应该:
<?php
...
class Keys {
public $ids = array(1, 2, 3, 4, 5, 6);
public $fnames = array("Joan", "Max", "Lori", "William", "Emily", "James");
public $lnames = array("Williams", "Helder", "Doe", "Must", "Deen", "Harthwell");
public $ages = array(32, 15, 19, 25, 17, 8);
}
$keys = new Keys; // instiantate an object as an instance of Keys
$sqlQueries = array(); // empty array to make SQL queries
for($i = 0; $i < 6; $i++) {
foreach($keys as $field => $value) {
for($j = 0; $j < count($value); $j++) {
array_push($sqlQueries, "INSERT INTO students VALUES($value[$j])");
}
}
} // adds queries to array
for($i = 0; $i < 6; $i++) {
if(mysqli_query($connection, $sqlQueries[$i])) {
echo "Data added successfully!";
} else {
die("Couldn't add data to table: " . mysqli_error($connection));
}
} // validates queries
...
?>
我创建了一个名为Keys
的类,该类具有我想要的SQL查询值。 我定义一个对象作为此新类的实例。 然后,定义将要实现的查询的空数组。 在第一个循环内,我尝试使用对象中的值创建查询。 每个完成的查询都“推送”到$sqlQueries
数组。 在第二个循环中,我验证查询。 但是,我的输出出现以下错误:
Couldn't add data to table: Column count doesn't match value count at row 1
我知道这意味着表的数据量甚至不相等。 但是我不知道为什么会有这个问题。 我看过很多资料,但没有一个提供帮助。
有人有主意吗?
我尝试了所有3个答案的方法,而在所有这些答案中,@ lps的答案当前距离我的解决方案最近。 现在,我的错误是:
Couldn't add data to table: Unknown column 'age' in 'field list'
一个新的答案出现了,实现了我的代码中的错误,然后就完成了。 但是,现在我有一个错误这样说:
Couldn't add data to table: Unknown column 'Joan' in 'field list'
@lps的答案下有一个注释,该注释消除了有关未知“ Joan”列的错误。 现在,我收到一条错误消息:
Couldn't add data to table: Duplicate entry '1' for key 'PRIMARY'
我的问题解决了! 这是我的最终代码:
<?php
...
class Keys {
public $fnames = array("Joan", "Max", "Lori", "William", "Emily", "James");
public $lnames = array("Williams", "Helder", "Doe", "Must", "Deen", "Harthwell");
public $ages = array(32, 15, 19, 25, 17, 8);
}
$keys = new Keys; // instiantate an object as an instance of Keys
$sqlQueries = array(); // empty array to make SQL queries
for($i = 0; $i < 6; $i++) {
$query = "INSERT INTO students (fname, lname, avg_grade) VALUES "; // base query
$values = array(); // empty array of values
foreach($keys as $field => $value) {
array_push($values, $value[$i]); // pushes each value to $values array
}
$query .= "(" . implode(',', $values) . ")"; // adds each value of array to the query
array_push($sqlQueries, $query); // pushes complete query to $sqlQueries array
} // adds queries to the $sqlQueries array
var_dump($sqlQueries); // Just wanted to see my queries
$query = "SELECT * FROM students";
$result = mysqli_query($connection, $query);
if(mysqli_num_rows($result) > 0) {
mysqli_query($connection, "DELETE FROM students");
} // cleans out the table if there are any duplicate queries
for($i = 0; $i < 6; $i++) {
if(mysqli_query($connection, $sqlQueries[$i])) {
$recordID = mysqli_insert_id($connection);
echo "Data added successfully! The last inserted ID was " . $recordID; // outputs success message and gets last inserted ID
} else {
die("Couldn't add data to table: " . mysqli_error($connection)); // Outputs an error if there was a failure attempting to implement data
}
} // validates queries
...
?>
使用LPS解释的方法。 现在,您收到的消息意味着需要在数据库结构中创建一个名为age
的字段。 检查您的数据库,我很确定该字段age
不存在。
编辑:
我很高兴看到我以前的答案解决了您的错误,您现在遇到的新错误( Couldn't add data to table: Duplicate entry '1' for key 'PRIMARY'
)意味着数据库中的字段id
是primary
字段字段和此类字段不允许重复(重复)的值。 因此,我猜代码运行一次并在数据库中插入了值,现在又无法执行了,因为它发现字段id
已经存在值1
,并且代码中的错误处理程序停止了脚本。
要测试我是否正确,请尝试以下操作:
转到您的数据库,记录应该已经插入,删除它们并运行脚本,它应该可以正常运行,并且如果您检查数据库,记录应该又在那里。 让记录在那里并尝试运行脚本,如果再次收到相同的错误,则表示我是对的。
我可以考虑两个简单的方法来解决此问题(取决于您想要的最终行为):
1)每次插入新记录(可能是最佳选择):
确保字段id
具有属性autoincrement
并且不要尝试插入和ID,让MySQL为您创建ID。 就这样。
这样,第一次运行脚本Joan
的id
号为1,第二次运行的ID为Joan
记录为2条:ID号1
(首次运行脚本时创建)和ID 7
(使用此数字创建,因为它是在6
号James
之后创建的)。
更改在您的代码中如下所示:
class Keys {
// public $ids = array(1, 2, 3, 4, 5, 6);
public $fnames = array("Joan", "Max", "Lori", "William", "Emily", "James");
public $lnames = array("Williams", "Helder", "Doe", "Must", "Deen", "Harthwell");
public $ages = array(32, 15, 19, 25, 17, 8);
}
$keys = new Keys;
2)如果要手动管理ID(不推荐)
让您的数据库按原样进行结构,如果它与重复的条目有关,则忽略该错误消息。
为此,请查找以下代码块:
for($i = 0; $i < 6; $i++) {
if(mysqli_query($connection, $sqlQueries[$i])) {
echo "Data added successfully!";
} else {
die("Couldn't add data to table: " . mysqli_error($connection));
}
} // validates queries
并将其替换为:
for($i = 0; $i < 6; $i++) {
if(mysqli_query($connection, $sqlQueries[$i])) {
echo "Data added successfully!";
} else {
$mysqliError = mysqli_error($connection);
if(strpos($mysqliError, 'Couldn\'t add data to table: Duplicate entry \'') !== false && strpos($mysqliError, '\' for key \'PRIMARY\'') !== false){
die("Couldn't add data to table: " . $mysqliError);
}
}
} // validates queries
您将最终以每个字段作为查询
INSERT INTO students VALUES(1) INSERT INTO students VALUES(2)
等等,因为您一次要添加一个字段。
假设您想将INSERT INTO students VALUES(1, "Joan", "Williams", 32)
,则需要以其他方式构建查询。
到目前为止,准备好的语句是最简单的方法。
$statement = $db->prepare("INSERT INTO students VALUES(?,?,?,?)");
foreach($keys->ids as $k => $v)
{
$statement->bind_param("issi", $keys->ids[$k], $keys->fnames[$k], $keys->lnames[$k], $keys->ages[$k]);
$statement->execute();
}
结果SQL查询的格式不正确。 插入查询中的字段和值计数必须匹配。 如果未指定任何字段,则这些值必须与表的结构匹配。
现在,您的代码正在生成如下查询:
array(144) {
[0]=>
string(30) "INSERT INTO students VALUES(1)"
[1]=>
string(30) "INSERT INTO students VALUES(2)"
[2]=>
string(30) "INSERT INTO students VALUES(3)"
[3]=>
string(30) "INSERT INTO students VALUES(4)"
[4]=>
string(30) "INSERT INTO students VALUES(5)"
[5]=>
string(30) "INSERT INTO students VALUES(6)"
[6]=>
string(33) "INSERT INTO students VALUES(Joan)"
[7]=>
string(32) "INSERT INTO students VALUES(Max)"
[8]=>
string(33) "INSERT INTO students VALUES(Lori)"
[9]=>
string(36) "INSERT INTO students VALUES(William)"
[10]=>
string(34) "INSERT INTO students VALUES(Emily)"
[11]=>
string(34) "INSERT INTO students VALUES(James)"
[12]=>
string(37) "INSERT INTO students VALUES(Williams)"
[13]=>
string(35) "INSERT INTO students VALUES(Helder)"
[14]=>
string(32) "INSERT INTO students VALUES(Doe)"
[15]=>
string(33) "INSERT INTO students VALUES(Must)"
[16]=>
string(33) "INSERT INTO students VALUES(Deen)"
[17]=>
string(38) "INSERT INTO students VALUES(Harthwell)"
...
所以,改变
for($i = 0; $i < 6; $i++) {
foreach($keys as $field => $value) {
for($j = 0; $j < count($value); $j++) {
array_push($sqlQueries, "INSERT INTO students VALUES($value[$j])");
}
}
} // adds queries to array
至:
$string_fields = ['fnames', 'lnames'];
for($i = 0; $i < 6; $i++) {
$query = "INSERT INTO students (id, fname, lname, age) VALUES ";
$values = array();
foreach($keys as $field => $value) {
$value = $value[$i];
if(in_array($field, $string_fields)) {
$value = "'" . $value . "'";
}
array_push($values, $value);
}
$query .= "(" . implode(',', $values) . ")";
array_push($sqlQueries, $query);
} // adds queries to array
这将产生以下查询:
array(6) {
[0]=>
string(76) "INSERT INTO students (id, fname, lname, age) VALUES (1,'Joan','Williams',32)"
[1]=>
string(73) "INSERT INTO students (id, fname, lname, age) VALUES (2,'Max','Helder',15)"
[2]=>
string(71) "INSERT INTO students (id, fname, lname, age) VALUES (3,'Lori','Doe',19)"
[3]=>
string(75) "INSERT INTO students (id, fname, lname, age) VALUES (4,'William','Must',25)"
[4]=>
string(73) "INSERT INTO students (id, fname, lname, age) VALUES (5,'Emily','Deen',17)"
[5]=>
string(77) "INSERT INTO students (id, fname, lname, age) VALUES (6,'James','Harthwell',8)"
}
更改代码,使其与实际的students
表模式匹配。
您所拥有的查询如下:
string(30) "INSERT INTO students VALUES(1)"
[1] => string(30) "INSERT INTO students VALUES(2)"
[2] => string(30) "INSERT INTO students VALUES(3)"
[3] => string(30) "INSERT INTO students VALUES(4)"
[4] => string(30) "INSERT INTO students VALUES(5)"
[5] => string(30) "INSERT INTO students VALUES(6)"
[6] => string(33) "INSERT INTO students VALUES(Joan)"
这里有几个问题:您没有指定需要输入的字段,一次仅传递1个字段,也没有引用字符串。 更好的方法是:
$queries = [];
foreach($keys->ids as $k => $v) {
$queries[] = "INSERT INTO students (id,first_name,last_name,age) VALUES ({$keys->ids[$k]},'{$keys->fnames[$k]}','{$keys->lnames[$k]}',{$keys->ages[$k]})";
}
更好的方法是使用准备好的语句,然后将其插入此循环中,而不是再次循环遍历这些语句。
您应该使用ORM或ActiveRecord样式的数据访问层。 您正在走一条崎well不平的道路,而没有意识到。
<?php
class Keys {
public $ids = array(1, 2, 3, 4, 5, 6);
public $fnames = array("Joan", "Max", "Lori", "William", "Emily", "James");
public $lnames = array("Williams", "Helder", "Doe", "Must", "Deen", "Harthwell");
public $ages = array(32, 15, 19, 25, 17, 8);
}
$keys = new Keys;
$str='(';
for ($i=0; $i <6 ; $i++) {
foreach ($keys as $key => $value) {
$str.=$value[$i].',';
}
$str=rtrim($str,',');
$str.='),(';
}
$str=rtrim($str,',(');
$query="INSERT INTO students (id, fname, lname, age) VALUES ".$str;
var_dump($query);
?>
您可以在将其插入数据库的情况下运行此查询。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.