Jus*_*rty 3 php mysql laravel laravel-5.6
我只是尝试了以下命令,但收到了不良结果。
DB::table('locations')->insert([
['code' => 'YC', 'name' => 'York Clifton'],
['code' => 'YK', 'name' => 'York'],
['postcode' => 'DR1', 'name' => 'Jason'],
['postcode' => 'DLR', 'name' => 'Beckton']
]);
Run Code Online (Sandbox Code Playgroud)
上面将这样在表中插入数据:
DB::table('locations')->insert([
['code' => 'YC', 'name' => 'York Clifton'],
['code' => 'YK', 'name' => 'York'],
['postcode' => 'DR1', 'name' => 'Jason'],
['postcode' => 'DLR', 'name' => 'Beckton']
]);
Run Code Online (Sandbox Code Playgroud)
位置表是使用以下代码段构建的:
$table->string('name', 100);
$table->string('code', 4)->nullable();
$table->string('postcode', 10)->nullable();
Run Code Online (Sandbox Code Playgroud)
自然,我想要的结果是在数据库中插入四行。前两个将填充code和name字段,而后两个插入将填充postcode和name。
我看过的文档说:
查询构建器还提供用于将记录插入数据库表的插入方法。insert方法接受一个列名和值的数组:
您甚至可以通过传递一个数组数组,通过一次插入调用将多个记录插入表中。每个数组代表要插入表中的一行。
我不完全确定Laravel在幕后做什么,但是似乎它会先构建insert语句,然后插入数据,而忽略列名键。
为避免该问题,我只用不同的列名分隔了插入语句。
这使我想到,如果所有记录都是多余的(除了第一个数组中的键除外),为什么还要麻烦拥有所有记录的列键?为什么没有两个用于insert方法的参数;一个带有列名数组,另一个带有数据。
文档没有说数组键必须全部相同,所以如果我遗漏了某些东西,那么如果有人可以提供一些无法理解的信息,我将不胜感激。
使用不同的列名时,如何在表中插入多行?
查看Laravel的代码,就可以看到这种行为的原因。显然,Laravel将插入查询编译为批处理插入,而不是将每个传递的数组编译为单独的插入查询。
在insert方法中,您可以查看查询的生成方式:
$sql = $this->grammar->compileInsert($this, $values);
Run Code Online (Sandbox Code Playgroud)
如果您在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";
Run Code Online (Sandbox Code Playgroud)
因此,基本上,您的插入调用将执行查询:
INSERT INTO `locations` (`code`, `name`)
VALUES ('YC', 'York Clifton'),
('YK', 'York'),
('DR1', '...')
Run Code Online (Sandbox Code Playgroud)
但是,您可以通过在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']
]);
Run Code Online (Sandbox Code Playgroud)