drupal学习之-批量添加和join使用

来源:互联网 发布:情感分类算法 编辑:程序博客网 时间:2024/05/02 05:07

原文:http://drupal.org/node/310079

插入查询必须使用查询构造器对象,不同的数据库需要对LOB字段(大对象,比如MySQL的TEXT类型)和BLOB字段(二进制大对象)的特殊处理,所以需要使用抽象层来适应不同数据库驱动处理的需要。

插入查询从以下方式使用db_insert()函数开始:

<?php
$query= db_insert('node',$options);
?>

这就创建了一个可以插入多个记录到node表里的插入查询对象。注意这里的表名外面也不需要大括号,查询构造器会自动处理。

插入查询使用了流畅API(Fluent API)设计,也就是说,所有的方法(除了execute())都会返回查询对象自身以允许使用链式调用。在大多数情况下,这意味着查询对象就完全不需要被保存成变量了。

插入查询对象支持数种使用模式以适应不同的需要。通常的工作流包括指定要插入数据的字段,指定要插入字段的数据,然后执行这个查询。下面列出了通常推荐使用的一些使用模式。

紧凑形式

对大多插入查询推荐的形式是紧凑形式:

<?php
$nid= db_insert('node')
  ->fields(array(
    'title'=>'Example',
    'uid'=>1,
    'created'=> REQUEST_TIME,
  ))
  ->execute();
?>

这将产生一个等价的如下查询:

INSERT INTO {node} (title, uid, created) VALUES (‘Example’, 1, 1221717405);

<?php
db_insert('node')
?>

这一行创建了一个针对node表的新查询对象。

<?php
  ->fields(array(
    'title'=>'Example',
    'uid'=>1,
    'created'=> REQUEST_TIME,
  ))
?>

fields()方法有很多种形式的参数,不过最常用的是单个关联数组的形式。数组的键是将要插入数据表的列名,数组的值是对应的要插入的值。这将会对指定表执行一个选择查询。

<?php
  ->execute();
?>

调用execute()方法会执行这个查询,在这个方法调用之前查询不会被执行。

与其它会返回插入查询对象自身的方法不同,如果插入查询中有个自增字段,那么execute()会返回一个这个字段的值。所以上面例子中,返回值直接赋给了$nid变量。如果没有自增字段,execute()的返回的将是一个未定义值,不能使用。

多数时候,这是使用插入查询最好的形式。

退化形式<?php
$nid= db_insert('node')
  ->fields(array('title','uid','created'))
  ->values(array(
    'title'=>'Example',
    'uid'=>1,
    'created'=> REQUEST_TIME,
  ))
  ->execute();
?>

这是之前查询的一种更冗长的等价形式,结果完全一样。

<?php
  ->fields(array('title','uid','created'))
?>

当fields()用一个索引数组而不是关联数组做参数被调用时,它只用于设定查询中要用到字段(数据列)而不需设定任何值,如果需要在稍后进行多个插入查询操作的时候会很有用。

<?php
  ->values(array(
    'title'=>'Example',
    'uid'=>1,
    'created'=> REQUEST_TIME,
  ))
?>

这个方法指定了一个关联数组,包含要插入数据库的字段名和值。values()方法也可以使用索引数组,如果使用的是索引数组,值的顺序必须和fields()方法中设定的字段的顺序相同。如果使用的是关联数组则可以是任意顺序。通常使用关联数组会有更好的可读性。

这种查询形式很少使用,通常紧凑模式会更好。在通常情况下只适合分开fields()和values()进行多次插入查询。

多插入形式

插入查询对象也可以多次进行值的设定,也就是说,values()可以被多次调用,以便顺序执行多个插入语句。特别是有可能这种操作会带来数据库兼容性问题。对于大多数数据库来说,多次插入语句将会在一次事务操作中一起执行以便更好的数据整合和提高速度,在MySQL中这将会使用MySQL的多值插入语法。

<?php
$values=array(
  array(
    'title'=>'Example',
    'uid'=>1,
    'created'=> REQUEST_TIME,
  ),
  array(
    'title'=>'Example 2',
    'uid'=>1,
    'created'=> REQUEST_TIME,
  ),
  array(
    'title'=>'Example 3',
    'uid'=>2,
    'created'=> REQUEST_TIME,
  ),
);
$query= db_insert('node')->fields(array('title','uid','created'));
foreach($valuesas$record){
  $query->values($record);
}
$query->execute();
?>

上面的例子将会同时执行三段插入语句作为一次操作,使用的是对于特定数据库驱动来说最有效率的方式。注意这里我们将查询对象保存到一个变量当中,这样我们可以循环遍历$values并且重复调用values()方法。

在原始码中,上面的例子等效于以下三个查询:

INSERT INTO {node} (title, uid, created) VALUES ('Example', 1, 1221717405);INSERT INTO {node} (title, uid, created) VALUES ('Example2', 1, 1221717405);INSERT INTO {node} (title, uid, created) VALUES ('Example3', 2, 1221717405);

注意在多插入查询中execute()的返回值是未定义的,不应该被使用,因为它非常依赖于使用的数据库驱动。

基于查询结果的插入

如果你希望用另一个表里查询的结果来填充一个表,你既可以在源表中使用SELECT,把数据读取到PHP中然后插入到新表,也只可以执行一个INERT INTO…SELECT FROM查询把所有选择查询中返回的记录都填充到插入查询中。

在这个例子中,我们希望建立一个叫“mytable”的表,包含系统中所有page类型的节点的节点id和用户名。

Drupal 6<?php
db_query('INSERT INTO {mytable} (nid, name) SELECT n.nid, u.name FROM {node} n LEFT JOIN {users} u on n.uid = u.uid WHERE n.type = "%s"',array('page'));
?>Drupal 7<?php
// 建立SELECT查询。
$query= db_select('node','n');
// 连接用户表。
$query->join('users','u','n.uid = u.uid');
// 添加需要的字段。
$query->addField('n','nid');
$query->addField('u','name');
// 添加只查询page节点的条件。
$query->condition('type','page');

// 执行查询
db_insert('mytable')
  ->from($query)
  ->execute();
?>缺省值

在通常情况下,如果不给字段指定一个值,那么由数据表的构架(schema)定义的缺省值将会被自动插入。有些时候,比如你希望整个记录都使用缺省值的情况下,你需要明确的告诉数据库使用缺省值。要明确的告诉数据库使用缺省值,使用useDefaults()方法。

<?php
$query->useDefaults(array('field1','field2'));
?>

这一行表明了查询将对fields和fields2使用数据库定义的缺省值。注意如果同时对一个字段使用useDefault()和values()会出现错误抛出一个异常。