2014-10-27 3 views
0

Я пытаюсь следующее CakePHP 3:Как использовать вставку в построителе запросов вставить несколько записей?

$newUsers = [ 
     [ 
      'username' => 'Felicia', 
      'age' => 27, 
     ], 
     [ 
      'username' => 'Timmy', 
      'age' => 71, 
     ], 
    ]; 

    $insertQuery = $this->Users->query(); 

    $insertQuery->insert(array_keys($newUsers[0])) 
       ->values($newUsers) 
       ->execute(); 

Я получаю следующее сообщение об ошибке:

Error: SQLSTATE[21S01]: Insert value list does not match column list: 1136 Column count doesn't match value count at row 1 

SQL Query: INSERT INTO users (username, age) VALUES (:c0, :c1, :c2, :c3) 

Я ожидал INSERT INTO users (username, age) VALUES (:c0, :c1), (:c2, :c3); как запрос.

Я включил журнал для конфигурации базы данных, и я вижу:

2014-10-27 16:10:26 Debug: INSERT INTO users (username, age) VALUES (NULL, NULL, 'Array', 'Array') 

Пожалуйста, помогите мне понять, если я неправильно понял потенциал использования конструктора запросов в CakePHP 3.x

ответ

3

Просто испытанный. Это работает.

$newUsers = [ 
     [ 
      'username' => 'Felicia', 
      'age' => 27, 
     ], 
     [ 
      'username' => 'Timmy', 
      'age' => 71, 
     ], 
    ]; 

    $columns = array_keys($newUsers[0]); 

Предупреждение! Есть два способа сделать массовую вставку. Это один из способов:

$insertQuery = $this->Users->query(); 

    $newUsersValuesExpression = new ValuesExpression($columns, $insertQuery->typeMap()->types([])); 
    $newUsersValuesExpression->values($newUsers); 

    $insertQuery->insert($columns) 
       ->values($newUsersValuesExpression) 
       ->execute(); 

Как было предложено ndm, я предпочитаю этот путь.

$insertQuery = $this->Users->query(); 

    $insertQuery->insert($columns); 

    // you must always alter the values clause AFTER insert 
    $insertQuery->clause('values')->values($newUsers); 

    $insertQuery->execute(); 
3

Вы можете объединить несколько value() вызовов:

// ... 

foreach($newUsers as $values) 
{ 
    $query->values($values); 
} 
$query->execute(); 

или модифицировать ValuesExpression объект непосредственно (доступен через Query::clause()), который имеет values() метод, который позволяет установить все данные сразу:

// ... 

$query->clause('values')->values($newUsers); 
$query->execute(); 
+0

Я думаю, вы не указали это правильно, но спасибо! Вы указали мне еще один способ получить значение ValuesExpression –

+0

@KimStacks. Как вы считаете, неправильно сформулировано? Отсутствует тот факт, что значения должны применяться после вызова 'insert()'? Как правило, это нужно делать. Также обратите внимание, что нет необходимости повторно применять экземпляр 'ValuesExpression'. – ndm

+0

К сожалению, вы были правы. Я изменю свой ответ. Человек, ты хороший. Как долго вы используете Cake3? –