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

时间:2016-07-28 18:32:08

标签: php mysqli

我无法解释我的问题,但这里的代码应该是:

<?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查询值。我将一个对象定义为这个新类的一个实例。然后,我定义了一个我要实现的查询的空数组。在第一个循环中,我尝试使用my对象中的值创建查询。每个完成的查询都是&#34;推送&#34;到$sqlQueries数组。在第二个循环中,我验证查询。但是,我在输出中收到以下错误:

Couldn't add data to table: Column count doesn't match value count at row 1

我知道这意味着数据量与表格无关。但我无法弄清楚为什么我有这个问题。我看了很多来源,但没有一个帮助过。

有没有人有想法?

编辑:

我尝试了所有3个答案的方法,并且在所有答案中,@ lps&#39;答案是目前最接近我的解决方案。现在,我的错误是:

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&#39;下的评论答案进来了,这消除了关于未知的错误&Joan&#39;柱。现在,我收到错误说:

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
    ...
?>

6 个答案:

答案 0 :(得分:3)

使用LPS解释的方法。您现在获得的消息意味着需要在数据库结构中创建名为age的字段。检查您的数据库,我很确定字段age不存在。

编辑:

我很高兴看到我之前的回答解决了您的错误,您现在收到的新错误(Couldn't add data to table: Duplicate entry '1' for key 'PRIMARY')表示数据库中的字段idprimary字段,此类字段不允许重复(重复)值。所以,我想代码运行良好一次,并在数据库中插入值,现在它不能再次执行,因为它发现字段1中已经存在值id并且错误处理程序在你的代码停止了脚本。

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

转到你的数据库,应该已经插入了记录,删除它们并运行脚本,它应该运行没有问题,如果你检查你的数据库,记录应该再次存在。让记录在那里并尝试运行脚本,如果再次收到相同的错误,这意味着我是对的。

我可以用两个简单的选项来思考解决问题(取决于你想要的最终行为):

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

确保字段id具有属性autoincrement,并且不要尝试插入和ID,让MySQL为您创建ID。多数民众赞成。

这样,第一次运行脚本Joan时,id编号为1,第二次将有2条名称为Joan的记录: ID号1(第一次运行脚本时创建)和ID号7(使用此号码创建,因为它是在编号为James的{​​{1}}之后创建的)。

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

6
  • 请注意,我刚评论了ID部分,但您也可以将其删除。

2)如果您想手动管理ID(不推荐)

让您的数据库结构如此,如果它与重复的条目相关,则忽略错误消息。

为此,请查找此块:

 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;

将其替换为:

   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

答案 1 :(得分:1)

您将最终将每个字段作为查询

INSERT INTO students VALUES(1) INSERT INTO students VALUES(2)

sqlQueries中的

等因为你一次添加一个字段。

假设您需要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();
}

答案 2 :(得分:1)

生成的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表架构匹配。

答案 3 :(得分: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)"

这里有几个问题:您没有指定需要进入哪个字段,您一次只传递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]})";
}

更好的方法是使用预处理语句,并将它们插入到这个循环中,而不是再次遍历语句。

答案 4 :(得分:0)

您应该使用ORM或ActiveRecord样式的数据访问层。你在没有意识到的情况下走在一条踩踏的路上。

答案 5 :(得分:0)

    <?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);
?>

您可以在其中运行此查询,将其插入数据库。