繁体   English   中英

为什么计数与SQL查询的值不匹配?

[英]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'

编辑2:

一个新的答案出现了,实现了我的代码中的错误,然后就完成了。 但是,现在我有一个错误这样说:

Couldn't add data to table: Unknown column 'Joan' in 'field list'

编辑3:

@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' )意味着数据库中的字段idprimary字段字段和此类字段不允许重复(重复)的值。 因此,我猜代码运行一次并在数据库中插入了值,现在又无法执行了,因为它发现字段id已经存在值1 ,并且代码中的错误处理程序停止了脚本。

要测试我是否正确,请尝试以下操作:

转到您的数据库,记录应该已经插入,删除它们并运行脚本,它应该可以正常运行,并且如果您检查数据库,记录应该又在那里。 让记录在那里并尝试运行脚本,如果再次收到相同的错误,则表示我是对的。

我可以考虑两个简单的方法来解决此问题(取决于您想要的最终行为):

1)每次插入新记录(可能是最佳选择):

确保字段id具有属性autoincrement并且不要尝试插入和ID,让MySQL为您创建ID。 就这样。

这样,第一次运行脚本Joanid号为1,第二次运行的ID为Joan记录为2条:ID号1 (首次运行脚本时创建)和ID 7 (使用此数字创建,因为它是在6James之后创建的)。

更改在您的代码中如下所示:

 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;
  • 请注意,我只是评论了ID部分,但您也可以删除它。

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM