翻译者:长风Drupal开发团队(成都长风云信息技术有限公司)
Drupal开发中,合并查询是一种特殊类型的混合查询。虽然在SQL 2003规范中为它们定义了语法,但实际上没有数据库支持标准语法。然而,大多数使用特定于数据库的语法提供一些替代的实现。Drupal中的合并查询生成器将合并查询的概念抽象为结构化对象,该结构对象可以被编译成每个数据库的适当语法。这些有时被称为“UPSERT”查询,UPDATE 和INSERT的组合。
一般意义上,合并查询是插入查询和更新查询的组合。如果满足给定条件,如排给定主键已经存在,则更新运行查询。如果没有,插入查询运行。在大多数情况下,它相当于:
if ($connection->query("SELECT COUNT(*) FROM {example} WHERE id = :id", [':id' => $id])->fetchField()) {
// Run an update using WHERE id = $id}else {
// Run an insert, inserting $id for id }
实际的实现从数据库到数据库变化很大。请注意,虽然合并查询在概念上是原子操作,但它们可能是或可能不是真正的原子依赖于特定数据库的实现。MySQL实现是一个单原子查询,但退化情况(以上)不是。
下面列出了用于合并查询的最常见的习惯用法。
$connection->merge('example')
->key(['name' => $name])
->fields([
'field1' => $value1,
'field2' => $value2,
])
->execute();
在上面的例子中,我们指示查询在“example”表操作。然后我们指定一个关键字段,“name”,使用$name值。然后,我们指定要设置的值数组。
如果表中已经存在的字段“name”有$name,然后field1和field2将被更新。如果这一行不存在,则将创建在这条记录,字段有vlaue $value1,和value $value2。因此,在查询结束,最终的结果是取决于name这个字段的值$name是否存在。
设置条件
在Drupal开发的一些实际应用中,您可能希望设置不同的值,取决于是否备案,由key()字段标识,已经存在。有两种方法可以做到这一点。
$connection->merge('example')
->insertFields([
'field1' => $value1,
'field2' => $value2,
])
->updateFields([
'field1' => $alternate1,
])
->key(['name' => $name])
->execute();
上面的示例将与第一个实例相同,除了如果记录已经存在并且我们正在更新它,字段1将被设置为$alternate1 而不是$Value1,字段2不会受到影响。的updateFields() 方法接受的价值观或两并行数值数组一个数组,必须以相同的顺序一个字段对应一个值。
$connection->merge('example')
->key(['name' => $name])
->fields([
'field1' => $value1,
'field2' => $value2,
])
->expression('field1', 'field1 + :inc', [':inc' => 1])
->execute();
在这个drupal案例中,如果记录已经存在,那么field1将被设置为其当前值加1。这使得它对于“计数器查询”非常有用,在每次发生某个事件时,您希望在数据库中增加一些计数器。无论记录是否存在,Field2仍将被设置为相同的值。
注意,expression()可以多次调用,每一次场,应该如果已经存在的记录集的表达。第一个参数是场,二是SQL片段指示字段应被设置的表达,和可选的三参数占位符的值插入到表达阵列。
也没有要求,用于expression()领域已经出现在fields()。