如何在laravel中插入具有多个不同列的多行

dly7yett  于 2021-06-24  发布在  Mysql
关注(0)|答案(1)|浏览(324)

我只是尝试了下面的命令并收到了不希望的结果。

DB::table('locations')->insert([
    ['code' => 'YC', 'name' => 'York Clifton'],
    ['code' => 'YK', 'name' => 'York'],

    ['postcode' => 'DR1',  'name' => 'Jason'],
    ['postcode' => 'DLR',  'name' => 'Beckton']
]);

上述内容将在表格中插入如下数据:

Expected                                         Actual
+-----+--------------+------+----------+        +----+--------------+------+----------+
| id  |     name     | code | postcode |        | id |     name     | code | postcode |
+-----+--------------+------+----------+        +----+--------------+------+----------+
|   1 | York Clifton | YC   | NULL     |        |  1 | York Clifton | YC   | NULL     |
|   2 | York         | YK   | NULL     |        |  2 | York         | YK   | NULL     |
|   3 | Jason        | NULL | DR1      |        |  3 | DR1          | Jaso | NULL     |
|   4 | Beckton      | NULL | DLR      |        |  4 | DLR          | Beck | NULL     |
+-----+--------------+------+----------+        +----+--------------+------+----------+

位置表是使用以下代码段生成的:

$table->string('name', 100);
$table->string('code', 4)->nullable();
$table->string('postcode', 10)->nullable();

当然,我期望的结果是在数据库中插入四行;前两个将填充 code 以及 name 字段,而后两个插入将填充 postcode 以及 name .
我看过文件,上面写着:
查询生成器还提供了一种插入方法,用于将记录插入到数据库表中。insert方法接受列名和值的数组:
您甚至可以通过传递一个数组来调用insert,在表中插入多条记录。每个数组表示要插入到表中的行。
我不完全确定laravel在幕后做了什么,但它似乎预先构建了insert语句,然后插入数据,忽略了列名键。
为了避免这个问题,我只是用不同的列名分隔insert语句。
这让我想到,如果列键是多余的(第一个数组中的键除外),为什么还要为所有记录设置列键呢?为什么不为insert方法提供两个参数;一个是列名数组,另一个是数据。
文档中并没有说数组键必须是相同的,所以如果我遗漏了一些东西,那么如果有人能够提供一些关于为什么这样做不起作用的见解,我将不胜感激。

热释光;博士

当使用不同的列名时,如何在表中插入多行?

uinbv5nw

uinbv5nw1#

看看拉威尔的密码就知道这种行为的原因了。显然,laravel将insert查询编译为批插入,而不是作为每个传递数组的单独插入查询。
在insert方法中,您可以看到查询是如何生成的:

$sql = $this->grammar->compileInsert($this, $values);

如果你走得更远 compileInsert 方法,您将注意到查询的列仅从传递的第一个数组生成:

$columns = $this->columnize(array_keys(reset($values)));

// We need to build a list of parameter place-holders of values that are bound
// to the query. Each insert should have the exact same amount of parameter
// bindings so we will loop through the record and parameterize them all.
$parameters = [];

foreach ($values as $record) {
    $parameters[] = '('.$this->parameterize($record).')';
}

$parameters = implode(', ', $parameters);

return "insert into $table ($columns) values $parameters";

基本上,insert调用将执行查询:

INSERT INTO `locations` (`code`, `name`) 
VALUES ('YC', 'York Clifton'), 
       ('YK', 'York'),
       ('DR1', '...')

但是,您可以通过一次调用插入所有条目,方法是在locations表中指定所有列:

DB::table('locations')->insert([
    ['code' => 'YC', 'name' => 'York Clifton', 'postcode' => null],
    ['code' => 'YK', 'name' => 'York', 'postcode' => null],

    ['code' => null, 'name' => 'Jason', 'postcode' => 'DR1'],
    ['code' => null, 'name' => 'Beckton', 'postcode' => 'DLR']
]);

相关问题