查询构建器类

CodeIgniter 为你提供了查询构建器类的访问。这种模式允许你使用最小的脚本就可以在数据库中检索、插入和更新信息。在某些情况下,只需要一行或两行代码就可以执行数据库操作。 CodeIgniter 不要求每个数据库表都有自己的类文件。它提供了一个更简化的接口。

除了简单性之外,使用查询构建器功能的一个主要好处是,它允许你创建数据库独立的应用程序,因为查询语法是由每个数据库适配器生成的。它也允许进行更安全的查询,因为系统会自动对值进行转义。

备注

CodeIgniter 不支持数据库、表名和列名中使用点(.)。

SQL 注入保护

你可以使用查询构建器相当安全地生成 SQL 语句。但是,它不旨在防止无论你传递什么数据都防止 SQL 注入。

传递给查询构建器的参数可以是:
  1. 标识符,如字段(或表)名称

  2. 它们的

  3. SQL 字符串 的一部分

查询构建器默认会转义所有

它还将尝试通过默认正确保护 标识符SQL 字符串 中的标识符。 但是,它的实现是为了在许多使用案例中工作良好,而不是旨在防止所有攻击。 因此,在没有适当验证的情况下,永远不要向它们馈送用户输入。

此外,许多方法都有 $escape 参数,可以设置为禁用转义。 如果将 $escape 设置为 false,查询构建器不提供任何保护, 所以你必须确保在将其传递给查询构建器之前已经适当地对它们进行了转义或保护。 使用 RawSql 指定原始 SQL 语句时也是如此。

加载查询构建器

可以通过数据库连接上的 table() 方法加载查询构建器。这会为你设置查询的 FROM 部分,并返回查询构建器类的新实例:

<?php

$db      = \Config\Database::connect();
$builder = $db->table('users');

只有在明确请求类时,才会将查询构建器加载到内存中,因此默认情况下不使用任何资源。

选择数据

以下方法允许你构建 SQL SELECT 语句。

Get

$builder->get()

运行选择查询并返回结果。可以自己使用以从表中检索所有记录:

<?php

$builder = $db->table('mytable');
$query   = $builder->get();  // Produces: SELECT * FROM mytable

第一个和第二个参数使你可以设置 limit 和 offset 子句:

<?php

$query = $builder->get(10, 20);
/*
 * Executes: SELECT * FROM mytable LIMIT 20, 10
 * (in MySQL. Other databases have slightly different syntax)
 */

你会注意到上面的方法被赋值给一个名为 $query 的变量,可用于显示结果:

<?php

$query = $builder->get();

foreach ($query->getResult() as $row) {
    echo $row->title;
}

有关结果生成的完整讨论,请访问 getResult*() 方法 页面。

$builder->getCompiledSelect()

编译选择查询,就像 $builder->get() 一样,但不运行查询。此方法简单地将 SQL 查询作为字符串返回。

例如:

<?php

$sql = $builder->getCompiledSelect();
echo $sql;
// Prints string: SELECT * FROM mytable

第一个参数使你可以设置查询构建器查询是否将重置(默认情况下,它将重置,就像使用 $builder->get() 一样):

<?php

echo $builder->limit(10, 20)->getCompiledSelect(false);
/*
 * Prints string: SELECT * FROM mytable LIMIT 20, 10
 * (in MySQL. Other databases have slightly different syntax)
 */

echo $builder->select('title, content, date')->getCompiledSelect();
// Prints string: SELECT title, content, date FROM mytable LIMIT 20, 10

上例中的关键是要注意第二个查询没有利用 limit(10, 20),但生成的 SQL 查询具有 LIMIT 20, 10。 这种结果的原因是因为第一个参数设置为 false

$builder->getWhere()

get() 方法相同,只是它允许你在第一个参数中添加 “where” 子句,而不是使用 $builder->where() 方法:

<?php

$query = $builder->getWhere(['id' => $id], $limit, $offset);

请阅读下面关于 where() 方法的更多信息。

Select

$builder->select()

允许你编写查询的 SELECT 部分:

<?php

$builder->select('title, content, date');
$query = $builder->get();
// Executes: SELECT title, content, date FROM mytable

备注

如果从表中选择所有 (*),则不需要使用此方法。如果省略,CodeIgniter 会假定你希望选择所有字段并自动添加 SELECT *

$builder->select() 接受一个可选的第二个参数。如果将其设置为 false,CodeIgniter 将不会尝试保护你的字段或表名。这在需要复合 select 语句的情况下很有用,其中自动转义字段可能会破坏它们。

<?php

$builder->select('(SELECT SUM(payments.amount) FROM payments WHERE payments.invoice_id=4) AS amount_paid', false);
$query = $builder->get();
RawSql

4.2.0 新版功能.

从 v4.2.0 开始, $builder->select() 接受一个 CodeIgniter\Database\RawSql 实例,它表示原始 SQL 字符串。

<?php

use CodeIgniter\Database\RawSql;

$sql = 'REGEXP_SUBSTR(ral_anno,"[0-9]{1,2}([,.][0-9]{1,3})([,.][0-9]{1,3})") AS ral';
$builder->select(new RawSql($sql));
$query = $builder->get();

警告

当你使用 RawSql 时,必须手动对值和标识符进行转义。否则可能会导致 SQL 注入。

$builder->selectMax()

为查询编写一个 SELECT MAX(field) 部分。你可以选择包括第二个参数以重命名结果字段。

<?php

$builder->selectMax('age');
$query = $builder->get();
// Produces: SELECT MAX(age) as age FROM mytable

$builder->selectMax('age', 'member_age');
$query = $builder->get();
// Produces: SELECT MAX(age) as member_age FROM mytable

$builder->selectMin()

为查询编写一个 SELECT MIN(field) 部分。与 selectMax() 一样,你可以选择包括第二个参数以重命名结果字段。

<?php

$builder->selectMin('age');
$query = $builder->get();
// Produces: SELECT MIN(age) as age FROM mytable

$builder->selectAvg()

为查询编写一个 SELECT AVG(field) 部分。与 selectMax() 一样,你可以选择包括第二个参数以重命名结果字段。

<?php

$builder->selectAvg('age');
$query = $builder->get();
// Produces: SELECT AVG(age) as age FROM mytable

$builder->selectSum()

为查询编写一个 SELECT SUM(field) 部分。与 selectMax() 一样,你可以选择包括第二个参数以重命名结果字段。

<?php

$builder->selectSum('age');
$query = $builder->get();
// Produces: SELECT SUM(age) as age FROM mytable

$builder->selectCount()

为查询编写一个 SELECT COUNT(field) 部分。与 selectMax() 一样,你可以选择包括第二个参数以重命名结果字段。

备注

此方法与 groupBy() 一起使用时特别有用。有关计数结果的更多信息,请参阅 countAll()countAllResults()

<?php

$builder->selectCount('age');
$query = $builder->get();
// Produces: SELECT COUNT(age) as age FROM mytable

$builder->selectSubquery()

在 SELECT 部分添加子查询。

$subquery = $db->table('countries')->select('name')->where('id', 1);
$builder  = $db->table('users')->select('name')->selectSubquery($subquery, 'country');
$query    = $builder->get();
// Produces: SELECT `name`, (SELECT `name` FROM `countries` WHERE `id` = 1) `country` FROM `users`

From

$builder->from()

允许你编写查询的 FROM 部分:

<?php

$builder = $db->table('users');
$builder->select('title, content, date');
$builder->from('mytable');
$query = $builder->get();
// Produces: SELECT title, content, date FROM users, mytable

备注

如前所示,可以在 $db->table() 方法中指定 FROM 部分。对 from() 的额外调用将向 FROM 部分添加更多表。

子查询

$builder->fromSubquery()

允许你将 FROM 查询的一部分编写为子查询。

这是我们将子查询添加到现有表的地方:

<?php

$subquery = $db->table('users');
$builder  = $db->table('jobs')->fromSubquery($subquery, 'alias');
$query    = $builder->get();
// Produces: SELECT * FROM `jobs`, (SELECT * FROM `users`) `alias`

使用 $db->newQuery() 方法将子查询设置为主表:

<?php

$subquery = $db->table('users')->select('id, name');
$builder  = $db->newQuery()->fromSubquery($subquery, 't');
$query    = $builder->get();
// Produces: SELECT * FROM (SELECT `id`, `name` FROM users) `t`

Join

$builder->join()

允许你编写查询的 JOIN 部分:

<?php

$builder = $db->table('blogs');
$builder->select('*');
$builder->join('comments', 'comments.id = blogs.id');
$query = $builder->get();
/*
 * Produces:
 * SELECT * FROM blogs JOIN comments ON comments.id = blogs.id
 */

如果需要在一个查询中进行多个连接,可以进行多次方法调用。

如果需要特定类型的 JOIN,可以通过方法的第三个参数指定。选项是:leftrightouterinnerleft outerright outer

<?php

$builder->join('comments', 'comments.id = blogs.id', 'left');
// Produces: LEFT JOIN comments ON comments.id = blogs.id
RawSql

4.2.0 新版功能.

从 v4.2.0 开始, $builder->join() 接受一个 CodeIgniter\Database\RawSql 实例,它表示原始 SQL 字符串。

<?php

use CodeIgniter\Database\RawSql;

$sql = 'user.id = device.user_id AND ((1=1 OR 1=1) OR (1=1 OR 1=1))';
$builder->join('user', new RawSql($sql), 'LEFT');
// Produces: LEFT JOIN "user" ON user.id = device.user_id AND ((1=1 OR 1=1) OR (1=1 OR 1=1))

警告

当你使用 RawSql 时,必须手动对值和标识符进行转义。否则可能会导致 SQL 注入。

查找特定数据

Where

$builder->where()

此方法使用五种方法之一启用设置 WHERE 子句:

备注

除了使用自定义字符串外,传递给此方法的所有值都会自动转义,生成更安全的查询。

备注

$builder->where() 接受一个可选的第三个参数。如果将其设置为 false,CodeIgniter 将不会尝试保护你的字段或表名。

1. 简单的键/值方法
<?php

$builder->where('name', $name);
// Produces: WHERE name = 'Joe'

请注意等号是自动添加的。

如果使用多个方法调用,它们将在它们之间用 AND 链在一起:

<?php

$builder->where('name', $name);
$builder->where('title', $title);
$builder->where('status', $status);
// WHERE name = 'Joe' AND title = 'boss' AND status = 'active'
2. 自定义键/值方法

你可以在第一个参数中包含一个运算符来控制比较:

<?php

$builder->where('name !=', $name);
$builder->where('id <', $id);
// Produces: WHERE name != 'Joe' AND id < 45
3. 关联数组方法
<?php

$array = ['name' => $name, 'title' => $title, 'status' => $status];
$builder->where($array);
// Produces: WHERE name = 'Joe' AND title = 'boss' AND status = 'active'

使用此方法也可以包含自己的运算符:

<?php

$array = ['name !=' => $name, 'id <' => $id, 'date >' => $date];
$builder->where($array);
4. 自定义字符串

你可以手动编写自己的子句:

<?php

$where = "name='Joe' AND status='boss' OR status='active'";
$builder->where($where);

警告

如果在字符串中使用用户提供的数据,则必须手动对值和标识符进行转义。否则可能会导致 SQL 注入。

<?php

$name  = $builder->db->escape('Joe');
$where = "name={$name} AND status='boss' OR status='active'";
$builder->where($where);
5. RawSql

4.2.0 新版功能.

从 v4.2.0 开始, $builder->where() 接受一个 CodeIgniter\Database\RawSql 实例,它表示原始 SQL 字符串。

<?php

use CodeIgniter\Database\RawSql;

$sql = "id > 2 AND name != 'Accountant'";
$builder->where(new RawSql($sql));

警告

当你使用 RawSql 时,必须手动对值和标识符进行转义。否则可能会导致 SQL 注入。

6. 子查询
<?php

// With closure
use CodeIgniter\Database\BaseBuilder;

$builder->where('advance_amount <', static function (BaseBuilder $builder) {
    $builder->select('MAX(advance_amount)', false)->from('orders')->where('id >', 2);
});
// Produces: WHERE "advance_amount" < (SELECT MAX(advance_amount) FROM "orders" WHERE "id" > 2)

// With builder directly
$subQuery = $db->table('orders')->select('MAX(advance_amount)', false)->where('id >', 2);
$builder->where('advance_amount <', $subQuery);

$builder->orWhere()

此方法与上面的方法相同,只是多个实例由 OR 连接:

<?php

$builder->where('name !=', $name);
$builder->orWhere('id >', $id);
// Produces: WHERE name != 'Joe' OR id > 50

$builder->whereIn()

生成一个与 AND 连接的 WHERE field IN (‘item’, ‘item’) SQL 查询(如果适用):

<?php

$names = ['Frank', 'Todd', 'James'];
$builder->whereIn('username', $names);
// Produces: WHERE username IN ('Frank', 'Todd', 'James')

你可以使用子查询而不是值数组:

<?php

// With closure
use CodeIgniter\Database\BaseBuilder;

$builder->whereIn('id', static function (BaseBuilder $builder) {
    $builder->select('job_id')->from('users_jobs')->where('user_id', 3);
});
// Produces: WHERE "id" IN (SELECT "job_id" FROM "users_jobs" WHERE "user_id" = 3)

// With builder directly
$subQuery = $db->table('users_jobs')->select('job_id')->where('user_id', 3);
$builder->whereIn('id', $subQuery);

$builder->orWhereIn()

生成一个与 OR 连接的 WHERE field IN (‘item’, ‘item’) SQL 查询(如果适用):

<?php

$names = ['Frank', 'Todd', 'James'];
$builder->orWhereIn('username', $names);
// Produces: OR username IN ('Frank', 'Todd', 'James')

你可以使用子查询而不是值数组:

<?php

// With closure
use CodeIgniter\Database\BaseBuilder;

$builder->orWhereIn('id', static function (BaseBuilder $builder) {
    $builder->select('job_id')->from('users_jobs')->where('user_id', 3);
});
// Produces: OR "id" IN (SELECT "job_id" FROM "users_jobs" WHERE "user_id" = 3)

// With builder directly
$subQuery = $db->table('users_jobs')->select('job_id')->where('user_id', 3);
$builder->orWhereIn('id', $subQuery);

$builder->whereNotIn()

生成一个与 AND 连接的 WHERE field NOT IN (‘item’, ‘item’) SQL 查询(如果适用):

<?php

$names = ['Frank', 'Todd', 'James'];
$builder->whereNotIn('username', $names);
// Produces: WHERE username NOT IN ('Frank', 'Todd', 'James')

你可以使用子查询而不是值数组:

<?php

// With closure
use CodeIgniter\Database\BaseBuilder;

$builder->whereNotIn('id', static function (BaseBuilder $builder) {
    $builder->select('job_id')->from('users_jobs')->where('user_id', 3);
});
// Produces: WHERE "id" NOT IN (SELECT "job_id" FROM "users_jobs" WHERE "user_id" = 3)

// With builder directly
$subQuery = $db->table('users_jobs')->select('job_id')->where('user_id', 3);
$builder->whereNotIn('id', $subQuery);

$builder->orWhereNotIn()

生成一个与 OR 连接的 WHERE field NOT IN (‘item’, ‘item’) SQL 查询(如果适用):

<?php

$names = ['Frank', 'Todd', 'James'];
$builder->orWhereNotIn('username', $names);
// Produces: OR username NOT IN ('Frank', 'Todd', 'James')

你可以使用子查询而不是值数组:

<?php

// With closure
use CodeIgniter\Database\BaseBuilder;

$builder->orWhereNotIn('id', static function (BaseBuilder $builder) {
    $builder->select('job_id')->from('users_jobs')->where('user_id', 3);
});
// Produces: OR "id" NOT IN (SELECT "job_id" FROM "users_jobs" WHERE "user_id" = 3)

// With builder directly
$subQuery = $db->table('users_jobs')->select('job_id')->where('user_id', 3);
$builder->orWhereNotIn('id', $subQuery);

查找类似数据

Like

$builder->like()

此方法使你可以生成 LIKE 子句,用于执行搜索。

备注

传递给此方法的所有值都会自动转义。

备注

可以通过向方法传递第五个参数 true 来强制所有 like* 方法变体执行不区分大小写的搜索。这将在可用的情况下使用特定于平台的功能,否则,它将强制值变为小写,即 WHERE LOWER(column) LIKE '%search%'。这可能需要为 LOWER(column) 而不是 column 创建索引才能有效。

1. 简单的键/值方法
<?php

$builder->like('title', 'match');
// Produces: WHERE `title` LIKE '%match%' ESCAPE '!'

如果使用多个方法调用,它们将在它们之间用 AND 链在一起:

<?php

$builder->like('title', 'match');
$builder->like('body', 'match');
// WHERE `title` LIKE '%match%' ESCAPE '!' AND  `body` LIKE '%match%' ESCAPE '!'

如果要控制通配符 (%) 的放置位置,可以使用可选的第三个参数。你的选项是 beforeafterboth (默认)。

<?php

$builder->like('title', 'match', 'before'); // Produces: WHERE `title` LIKE '%match' ESCAPE '!'
$builder->like('title', 'match', 'after');  // Produces: WHERE `title` LIKE 'match%' ESCAPE '!'
$builder->like('title', 'match', 'both');   // Produces: WHERE `title` LIKE '%match%' ESCAPE '!'
2. 关联数组方法
<?php

$array = ['title' => $match, 'page1' => $match, 'page2' => $match];
$builder->like($array);
/*
 * WHERE `title` LIKE '%match%' ESCAPE '!'
 *     AND  `page1` LIKE '%match%' ESCAPE '!'
 *     AND  `page2` LIKE '%match%' ESCAPE '!'
 */
3. RawSql

4.2.0 新版功能.

从 v4.2.0 开始, $builder->like() 接受一个 CodeIgniter\Database\RawSql 实例,它表示原始 SQL 字符串。

<?php

use CodeIgniter\Database\RawSql;

$sql    = "CONCAT(users.name, ' ', IF(users.surname IS NULL OR users.surname = '', '', users.surname))";
$rawSql = new RawSql($sql);
$builder->like($rawSql, 'value', 'both');

警告

当你使用 RawSql 时,必须手动对值和标识符进行转义。否则可能会导致 SQL 注入。

$builder->orLike()

此方法与上面相同,只是多个实例由 OR 连接:

<?php

$builder->like('title', 'match');
$builder->orLike('body', $match);
// WHERE `title` LIKE '%match%' ESCAPE '!' OR  `body` LIKE '%match%' ESCAPE '!'

$builder->notLike()

此方法与 like() 相同,只是它生成 NOT LIKE 语句:

<?php

$builder->notLike('title', 'match'); // WHERE `title` NOT LIKE '%match% ESCAPE '!'

$builder->orNotLike()

此方法与 notLike() 相同,只是多个实例由 OR 连接:

<?php

$builder->like('title', 'match');
$builder->orNotLike('body', 'match');
// WHERE `title` LIKE '%match% OR  `body` NOT LIKE '%match%' ESCAPE '!'

$builder->groupBy()

允许你编写查询的 GROUP BY 部分:

<?php

$builder->groupBy('title');
// Produces: GROUP BY title

你也可以传递多个值的数组:

<?php

$builder->groupBy(['title', 'date']);
// Produces: GROUP BY title, date

$builder->distinct()

向查询添加 DISTINCT 关键字

<?php

$builder->distinct();
$builder->get();
// Produces: SELECT DISTINCT * FROM mytable

$builder->having()

允许你编写查询的 HAVING 部分。有 2 种可能的语法,1 个参数或 2 个:

<?php

$builder->having('user_id = 45'); // Produces: HAVING user_id = 45
$builder->having('user_id', 45); // Produces: HAVING user_id = 45

你也可以传递多个值的数组:

<?php

$builder->having(['title =' => 'My Title', 'id <' => $id]);
// Produces: HAVING title = 'My Title', id < 45

如果你使用转义值的数据库,可以通过传递可选的第三个参数并将其设置为 false 来防止转义内容。

<?php

$builder->having('user_id', 45); // Produces: HAVING `user_id` = 45 in some databases such as MySQL
$builder->having('user_id', 45, false); // Produces: HAVING user_id = 45

$builder->orHaving()

having() 相同,只是使用 OR 分隔多个子句。

$builder->havingIn()

生成一个与 AND 相连的 HAVING 字段 IN (‘item’, ‘item’) SQL查询(如果适用):

<?php

$groups = [1, 2, 3];
$builder->havingIn('group_id', $groups);
// Produces: HAVING group_id IN (1, 2, 3)

你可以使用子查询而不是值数组:

<?php

// With closure
use CodeIgniter\Database\BaseBuilder;

$builder->havingIn('id', static function (BaseBuilder $builder) {
    $builder->select('user_id')->from('users_jobs')->where('group_id', 3);
});
// Produces: HAVING "id" IN (SELECT "user_id" FROM "users_jobs" WHERE "group_id" = 3)

// With builder directly
$subQuery = $db->table('users_jobs')->select('user_id')->where('group_id', 3);
$builder->havingIn('id', $subQuery);

$builder->orHavingIn()

生成一个与 OR 相连的 HAVING 字段 IN (‘item’, ‘item’) SQL查询(如果适用):

<?php

$groups = [1, 2, 3];
$builder->orHavingIn('group_id', $groups);
// Produces: OR group_id IN (1, 2, 3)

你可以使用子查询而不是值数组:

<?php

// With closure
use CodeIgniter\Database\BaseBuilder;

$builder->orHavingIn('id', static function (BaseBuilder $builder) {
    $builder->select('user_id')->from('users_jobs')->where('group_id', 3);
});
// Produces: OR "id" IN (SELECT "user_id" FROM "users_jobs" WHERE "group_id" = 3)

// With builder directly
$subQuery = $db->table('users_jobs')->select('user_id')->where('group_id', 3);
$builder->orHavingIn('id', $subQuery);

$builder->havingNotIn()

生成一个与 AND 相连的 HAVING 字段 NOT IN (‘item’, ‘item’) SQL查询(如果适用):

<?php

$groups = [1, 2, 3];
$builder->havingNotIn('group_id', $groups);
// Produces: HAVING group_id NOT IN (1, 2, 3)

你可以使用子查询而不是值数组:

<?php

// With closure
use CodeIgniter\Database\BaseBuilder;

$builder->havingNotIn('id', static function (BaseBuilder $builder) {
    $builder->select('user_id')->from('users_jobs')->where('group_id', 3);
});
// Produces: HAVING "id" NOT IN (SELECT "user_id" FROM "users_jobs" WHERE "group_id" = 3)

// With builder directly
$subQuery = $db->table('users_jobs')->select('user_id')->where('group_id', 3);
$builder->havingNotIn('id', $subQuery);

$builder->orHavingNotIn()

生成一个与 OR 相连的 HAVING 字段 NOT IN (‘item’, ‘item’) SQL查询(如果适用):

<?php

$groups = [1, 2, 3];
$builder->havingNotIn('group_id', $groups);
// Produces: OR group_id NOT IN (1, 2, 3)

你可以使用子查询而不是值数组:

<?php

// With closure
use CodeIgniter\Database\BaseBuilder;

$builder->orHavingNotIn('id', static function (BaseBuilder $builder) {
    $builder->select('user_id')->from('users_jobs')->where('group_id', 3);
});
// Produces: OR "id" NOT IN (SELECT "user_id" FROM "users_jobs" WHERE "group_id" = 3)

// With builder directly
$subQuery = $db->table('users_jobs')->select('user_id')->where('group_id', 3);
$builder->orHavingNotIn('id', $subQuery);

$builder->havingLike()

此方法使你可以为 HAVING 部分生成 LIKE 子句,用于执行搜索。

警告

传递给此方法的所有值都会自动转义。

警告

可以通过向方法传递第五个参数 true 来强制所有 havingLike*() 方法变体执行不区分大小写的搜索。这将在可用的情况下使用特定于平台的功能,否则,它将强制值变为小写,即 HAVING LOWER(column) LIKE '%search%'。这可能需要为 LOWER(column) 而不是 column 创建索引才能有效。

1. 简单的键/值方法
<?php

$builder->havingLike('title', 'match');
// Produces: HAVING `title` LIKE '%match%' ESCAPE '!'

如果使用多个方法调用,它们将在它们之间用 AND 链在一起:

<?php

$builder->havingLike('title', 'match');
$builder->havingLike('body', 'match');
// HAVING `title` LIKE '%match%' ESCAPE '!' AND  `body` LIKE '%match% ESCAPE '!'

如果要控制通配符 (%) 的放置位置,可以使用可选的第三个参数。你的选项是 beforeafterboth (默认)。

<?php

$builder->havingLike('title', 'match', 'before'); // Produces: HAVING `title` LIKE '%match' ESCAPE '!'
$builder->havingLike('title', 'match', 'after');  // Produces: HAVING `title` LIKE 'match%' ESCAPE '!'
$builder->havingLike('title', 'match', 'both');   // Produces: HAVING `title` LIKE '%match%' ESCAPE '!'
2. 关联数组方法
<?php

$array = ['title' => $match, 'page1' => $match, 'page2' => $match];
$builder->havingLike($array);
/*
 *  HAVING `title` LIKE '%match%' ESCAPE '!'
 *      AND  `page1` LIKE '%match%' ESCAPE '!'
 *      AND  `page2` LIKE '%match%' ESCAPE '!'
 */

$builder->orHavingLike()

此方法与上面相同,只是多个实例由 OR 连接:

<?php

$builder->havingLike('title', 'match');
$builder->orHavingLike('body', $match);
// HAVING `title` LIKE '%match%' ESCAPE '!' OR  `body` LIKE '%match%' ESCAPE '!'

$builder->notHavingLike()

此方法与 havingLike() 相同,只是它生成 NOT LIKE 语句:

<?php

$builder->notHavingLike('title', 'match');
// HAVING `title` NOT LIKE '%match% ESCAPE '!'

$builder->orNotHavingLike()

此方法与 notHavingLike() 相同,只是多个实例由 OR 连接:

<?php

$builder->havingLike('title', 'match');
$builder->orNotHavingLike('body', 'match');
// HAVING `title` LIKE '%match% OR  `body` NOT LIKE '%match%' ESCAPE '!'

排序结果

OrderBy

$builder->orderBy()

允许你设置 ORDER BY 子句。

第一个参数包含要排序的列的名称。

第二个参数让你设置所请求的排序方向 - ASC、DESC 或 random。

<?php

$builder->orderBy('title', 'DESC');
// Produces: ORDER BY `title` DESC

你也可以在第一个参数中传递自己的字符串:

<?php

$builder->orderBy('title DESC, name ASC');
// Produces: ORDER BY `title` DESC, `name` ASC

或者如果需要对多个字段进行排序,可以进行多次方法调用。

<?php

$builder->orderBy('title', 'DESC');
$builder->orderBy('name', 'ASC');
// Produces: ORDER BY `title` DESC, `name` ASC

如果选择 RANDOM 排序方向,则首参数将被忽略,除非指定数值种子。

<?php

$builder->orderBy('title', 'RANDOM');
// Produces: ORDER BY RAND()

$builder->orderBy(42, 'RANDOM');
// Produces: ORDER BY RAND(42)

限制或计数结果

Limit

$builder->limit()

允许你限制返回的行数:

<?php

$builder->limit(10);
// Produces: LIMIT 10

第二个参数允许你设置结果偏移量。

<?php

$builder->limit(10, 20);
// Produces: LIMIT 20, 10 (in MySQL. Other databases have slightly different syntax)

$builder->countAllResults()

允许你确定特定 Query Builder 查询中的行数。查询将接受 Query Builder 限制器,如 where()orWhere()like()orLike() 等。例如:

<?php

echo $builder->countAllResults(); // Produces an integer, like 25
$builder->like('title', 'match');
$builder->from('my_table');
echo $builder->countAllResults(); // Produces an integer, like 17

但是,此方法也会重置你可能传递给 select() 的任何字段值。如果需要保留它们,可以将第一个参数设置为 false

<?php

echo $builder->countAllResults(false); // Produces an integer, like 17

$builder->countAll()

允许你确定特定表中的行数。例如:

<?php

echo $builder->countAll(); // Produces an integer, like 25

countAllResult() 方法一样,此方法也会重置你可能传递给 select() 的任何字段值。如果需要保留它们,可以将第一个参数设置为 false

联合查询

Union

$builder->union()

用于合并两个或多个 SELECT 语句的结果。它将只返回唯一的结果。

<?php

$builder = $db->table('users')->select('id, name')->limit(10);
$union   = $db->table('groups')->select('id, name');
$builder->union($union)->get();
/*
 * Produces:
 * SELECT * FROM (SELECT `id`, `name` FROM `users` LIMIT 10) uwrp0
 * UNION SELECT * FROM (SELECT `id`, `name` FROM `groups`) uwrp1
 */

警告

对于正确使用某些 DBMS(如 MSSQL 和 Oracle),查询将被包装在 SELECT * FROM ( ... ) alias 中。 主查询总是具有 uwrp0 的别名。每个后续通过 union() 添加的查询都具有 uwrpN+1 的别名。

所有联合查询都将在主查询之后添加,而不考虑调用 union() 方法的顺序。也就是说, limit()orderBy() 方法将针对主查询,即使在 union() 之后调用。

在某些情况下,可能需要对查询结果进行排序或限制记录数。解决方案是使用通过 $db->newQuery() 创建的 wrapper。在下面的示例中,我们获取前 5 个用户 + 最后 5 个用户并按 id 排序:

<?php

$union   = $db->table('users')->select('id, name')->orderBy('id', 'DESC')->limit(5);
$builder = $db->table('users')->select('id, name')->orderBy('id', 'ASC')->limit(5)->union($union);

$db->newQuery()->fromSubquery($builder, 'q')->orderBy('id', 'DESC')->get();
/*
 * Produces:
 * SELECT * FROM (
 *      SELECT * FROM (SELECT `id`, `name` FROM `users` ORDER BY `id` ASC LIMIT 5) uwrp0
 *      UNION
 *      SELECT * FROM (SELECT `id`, `name` FROM `users` ORDER BY `id` DESC LIMIT 5) uwrp1
 * ) q ORDER BY `id` DESC
 */

$builder->unionAll()

行为与 union() 方法相同。但是,将返回所有结果,而不仅仅是唯一的结果。

分组查询

Group

查询分组允许你通过用括号将它们分组来创建复杂的 WHERE 子句。这将允许你创建具有复杂 WHERE 子句的查询。支持嵌套分组。例如:

<?php

$builder->select('*')->from('my_table')
    ->groupStart()
        ->where('a', 'a')
        ->orGroupStart()
            ->where('b', 'b')
            ->where('c', 'c')
        ->groupEnd()
    ->groupEnd()
    ->where('d', 'd')
    ->get();
/*
 * Generates:
 * SELECT * FROM (`my_table`) WHERE ( `a` = 'a' OR ( `b` = 'b' AND `c` = 'c' ) ) AND `d` = 'd'
 */

警告

分组需要平衡,请确保每个 groupStart() 都与 groupEnd() 匹配。

$builder->groupStart()

通过向查询的 WHERE 子句添加开括号来启动新的分组。

$builder->orGroupStart()

通过向查询的 WHERE 子句添加开括号并添加 OR 前缀来启动新的分组。

$builder->notGroupStart()

通过向查询的 WHERE 子句添加开括号并添加 NOT 前缀来启动新的分组。

$builder->orNotGroupStart()

通过向查询的 WHERE 子句添加开括号并添加 OR NOT 前缀来启动新的分组。

$builder->groupEnd()

通过向查询的 WHERE 子句添加闭括号来结束当前分组。

$builder->havingGroupStart()

通过向查询的 HAVING 子句添加开括号来启动新的分组。

$builder->orHavingGroupStart()

通过向查询的 HAVING 子句添加开括号并添加 OR 前缀来启动新的分组。

$builder->notHavingGroupStart()

通过向查询的 HAVING 子句添加开括号并添加 NOT 前缀来启动新的分组。

$builder->orNotHavingGroupStart()

通过向查询的 HAVING 子句添加开括号并添加 OR NOT 前缀来启动新的分组。

$builder->havingGroupEnd()

通过向查询的 HAVING 子句添加闭括号来结束当前分组。

插入数据

Insert

$builder->insert()

根据你提供的数据生成 insert 字符串并运行查询。你可以将一个**数组**或**对象**传递给该方法。下面是一个使用数组的示例:

<?php

use CodeIgniter\Database\RawSql;

$data = [
    'id'          => new RawSql('DEFAULT'),
    'title'       => 'My title',
    'name'        => 'My Name',
    'date'        => '2022-01-01',
    'last_update' => new RawSql('CURRENT_TIMESTAMP()'),
];

$builder->insert($data);
/* Produces:
    INSERT INTO mytable (id, title, name, date, last_update)
    VALUES (DEFAULT, 'My title', 'My name', '2022-01-01', CURRENT_TIMESTAMP())
*/

第一个参数是一个关联数组。

这是一个使用对象的示例:

<?php

class Myclass
{
    public $title   = 'My Title';
    public $content = 'My Content';
    public $date    = 'My Date';
}

$object = new Myclass();
$builder->insert($object);
// Produces: INSERT INTO mytable (title, content, date) VALUES ('My Title', 'My Content', 'My Date')

第一个参数是一个对象。

备注

RawSql 外,所有值都会自动转义,生成更安全的查询。

警告

当你使用 RawSql 时,必须手动对数据进行转义。否则可能会导致 SQL 注入。

$builder->ignore()

根据你提供的数据生成 insert ignore 字符串并运行查询。所以如果具有相同主键的条目已经存在,则不会插入查询。 你可以选择向方法传递一个**布尔值**。也可用于 insertBatchupdatedelete (若支持)。 下面是一个使用上述数组的示例:

<?php

$data = [
    'title' => 'My title',
    'name'  => 'My Name',
    'date'  => 'My date',
];

$builder->ignore(true)->insert($data);
// Produces: INSERT OR IGNORE INTO mytable (title, name, date) VALUES ('My title', 'My name', 'My date')

$builder->getCompiledInsert()

编译插入查询,就像 $builder->insert() 一样,但不运行查询。此方法简单地将 SQL 查询作为字符串返回。

例如:

<?php

$data = [
    'title' => 'My title',
    'name'  => 'My Name',
    'date'  => 'My date',
];

$sql = $builder->set($data)->getCompiledInsert();
echo $sql;
// Produces string: INSERT INTO mytable (`title`, `name`, `date`) VALUES ('My title', 'My name', 'My date')

第一个参数使你可以设置查询构建器查询是否将重置(默认情况下,它将重置,就像 $builder->insert() 一样):

<?php

echo $builder->set('title', 'My Title')->getCompiledInsert(false);
// Produces string: INSERT INTO mytable (`title`) VALUES ('My Title')

echo $builder->set('content', 'My Content')->getCompiledInsert();
// Produces string: INSERT INTO mytable (`title`, `content`) VALUES ('My Title', 'My Content')

之所以第二个查询有效,是因为第一个参数设置为 false

备注

此方法不适用于批量插入。

insertBatch

$builder->insertBatch()

根据你提供的数据生成 insert 字符串,并运行查询。你可以将一个**数组**或**对象**传递给该方法。下面是一个使用数组的示例:

<?php

$data = [
    [
        'title' => 'My title',
        'name'  => 'My Name',
        'date'  => 'My date',
    ],
    [
        'title' => 'Another title',
        'name'  => 'Another Name',
        'date'  => 'Another date',
    ],
];

$builder->insertBatch($data);
/*
 * Produces:
 * INSERT INTO mytable (title, name, date)
 *      VALUES ('My title', 'My name', 'My date'),
 *      ('Another title', 'Another name', 'Another date')
 */

第一个参数是一个关联数组。

备注

RawSql 外,所有值都会自动转义,生成更安全的查询。

警告

当你使用 RawSql 时,必须手动对数据进行转义。否则可能会导致 SQL 注入。

你也可以从查询中插入:

<?php

use CodeIgniter\Database\RawSql;

$query = 'SELECT user2.name, user2.email, user2.country
          FROM user2
          LEFT JOIN user ON user.email = user2.email
          WHERE user.email IS NULL';

$sql = $builder
    ->ignore(true)
    ->setQueryAsData(new RawSql($query), null, 'name, country, email')
    ->insertBatch();
/* MySQLi produces:
    INSERT IGNORE INTO `db_user` (`name`, `country`, `email`)
    SELECT user2.name, user2.email, user2.country
    FROM user2
    LEFT JOIN user ON user.email = user2.email
    WHERE user.email IS NULL
*/

备注

setQueryAsData() 可从 v4.3.0 开始使用。

备注

必须将选择查询的列别名为目标表的列名。

插入更新数据

Upsert

$builder->upsert()

4.3.0 新版功能.

根据你提供的数据生成插入更新字符串,并运行查询。你可以将一个**数组**或**对象**传递给该方法。默认情况下,约束将按顺序定义。首先选择主键,然后是唯一键。MySQL 将默认使用任何约束。下面是一个使用数组的示例:

<?php

$data = [
    'email'   => 'ahmadinejad@example.com',
    'name'    => 'Ahmadinejad',
    'country' => 'Iran',
];

$builder->upsert($data);
// MySQLi  produces: INSERT INTO.. ON DUPLICATE KEY UPDATE..
// Postgre produces: INSERT INTO.. ON CONFLICT.. DO UPDATE..
// SQLite3 produces: INSERT INTO.. ON CONFLICT.. DO UPDATE..
// SQLSRV  produces: MERGE INTO.. WHEN MATCHED THEN UPDATE.. WHEN NOT MATCHED THEN INSERT..
// OCI8    produces: MERGE INTO.. WHEN MATCHED THEN UPDATE.. WHEN NOT MATCHED THEN INSERT..

第一个参数是一个关联数组。

这是一个使用对象的示例:

<?php

class Myclass
{
    public $email   = 'ahmadinejad@example.com';
    public $name    = 'Ahmadinejad';
    public $country = 'Iran';
}

$object = new Myclass();
$builder->upsert($object);

第一个参数是一个对象。

备注

所有值都会自动转义,生成更安全的查询。

$builder->getCompiledUpsert()

4.3.0 新版功能.

编译插入更新查询,就像 $builder->upsert() 一样,但不运行查询。此方法简单地将 SQL 查询作为字符串返回。

例如:

<?php

$data = [
    'email'   => 'ahmadinejad@example.com',
    'name'    => 'Ahmadinejad',
    'country' => 'Iran',
];

$sql = $builder->setData($data)->getCompiledUpsert();
echo $sql;
/* MySQLi produces:
    INSERT INTO `db_user` (`country`, `email`, `name`)
    VALUES ('Iran','ahmadinejad@example.com','Ahmadinejad')
    ON DUPLICATE KEY UPDATE
    `country` = VALUES(`country`),
    `email` = VALUES(`email`),
    `name` = VALUES(`name`)
*/

备注

此方法不适用于批量插入更新。

upsertBatch

$builder->upsertBatch()

4.3.0 新版功能.

根据你提供的数据生成插入更新字符串,并运行查询。你可以将一个**数组**或**对象**传递给该方法。默认情况下,约束将按顺序定义。首先选择主键,然后是唯一键。MySQL 将默认使用任何约束。下面是一个使用数组的示例:

<?php

$data = [
    [
        'id'      => 2,
        'email'   => 'ahmadinejad@example.com',
        'name'    => 'Ahmadinejad',
        'country' => 'Iran',
    ],
    [
        'id'      => null,
        'email'   => 'pedro@example.com',
        'name'    => 'Pedro',
        'country' => 'El Salvador',
    ],
];

$builder->upsertBatch($data);
// MySQLi  produces: INSERT INTO.. ON DUPLICATE KEY UPDATE..
// Postgre produces: INSERT INTO.. ON CONFLICT.. DO UPDATE..
// SQLite3 produces: INSERT INTO.. ON CONFLICT.. DO UPDATE..
// SQLSRV  produces: MERGE INTO.. WHEN MATCHED THEN UPDATE.. WHEN NOT MATCHED THEN INSERT..
// OCI8    produces: MERGE INTO.. WHEN MATCHED THEN UPDATE.. WHEN NOT MATCHED THEN INSERT..

第一个参数是一个关联数组。

备注

所有值都会自动转义,生成更安全的查询。

你也可以从查询中插入更新:

<?php

$query = $this->db->table('user2')
    ->select('user2.name, user2.email, user2.country')
    ->join('user', 'user.email = user2.email', 'left')
    ->where('user.email IS NULL');

$additionalUpdateField = ['updated_at' => new RawSql('CURRENT_TIMESTAMP')];

$sql = $builder->setQueryAsData($query)
    ->onConstraint('email')
    ->updateFields($additionalUpdateField, true)
    ->upsertBatch();
/* MySQLi produces:
    INSERT INTO `db_user` (`country`, `email`, `name`)
    SELECT user2.name, user2.email, user2.country
    FROM user2
    LEFT JOIN user ON user.email = user2.email
    WHERE user.email IS NULL
    ON DUPLICATE KEY UPDATE
    `country` = VALUES(`country`),
    `email` = VALUES(`email`),
    `name` = VALUES(`name`),
    `updated_at` = CURRENT_TIMESTAMP
*/

备注

setQueryAsData()onConstraint()updateFields() 方法可从 v4.3.0 开始使用。

备注

必须将选择查询的列别名为目标表的列名。

$builder->onConstraint()

4.3.0 新版功能.

允许手动设置要用于插入更新的约束。这与 MySQL 不兼容,因为 MySQL 默认检查所有约束。

<?php

$data = [
    'id'      => 2,
    'email'   => 'ahmadinejad@example.com',
    'name'    => 'Ahmadinejad',
    'country' => 'Iran',
];

$builder->onConstraint('email')->upsert($data);
/* Postgre produces:
    INSERT INTO "db_user"("country", "email", "id", "name")
    VALUES ('Iran','ahmadinejad@example.com',2,'Ahmadinejad')
    ON CONFLICT("email")
    DO UPDATE SET
    "country" = "excluded"."country",
    "id" = "excluded"."id",
    "name" = "excluded"."name"
*/

此方法接受字符串或列数组。

$builder->updateFields()

4.3.0 新版功能.

允许手动设置执行插入更新时要更新的字段。

<?php

$data = [
    'id'      => 2,
    'email'   => 'ahmadinejad@example.com',
    'name'    => 'Ahmadinejad Zaghari',
    'country' => 'Afghanistan',
];

$builder->updateFields('name, country')->setData($data, null, '_upsert')->upsert();
/* SQLSRV produces:
    MERGE INTO "test"."dbo"."db_user"
    USING (
     VALUES ('Iran','ahmadinejad@example.com',2,'Ahmadinejad')
    ) "_upsert" ("country", "email", "id", "name")
    ON ("test"."dbo"."db_user"."id" = "_upsert"."id")
    WHEN MATCHED THEN UPDATE SET
    "country" = "_upsert"."country",
    "name" = "_upsert"."name"
    WHEN NOT MATCHED THEN INSERT ("country", "email", "id", "name")
    VALUES ("_upsert"."country", "_upsert"."email", "_upsert"."id", "_upsert"."name");
*/

此方法接受字符串、列数组或 RawSql。你还可以指定要更新的额外列,该列不包括在数据集中。这可以通过将第二个参数设置为 true 来完成。

<?php

$data = [
    [
        'id'      => 2,
        'email'   => 'ahmadinejad@example.com',
        'name'    => 'Ahmadinejad',
        'country' => 'Iran',
    ],
    [
        'id'      => null,
        'email'   => 'pedro@example.com',
        'name'    => 'Pedro',
        'country' => 'El Salvador',
    ],
];

$additionalUpdateField = ['updated_at' => new RawSql('CURRENT_TIMESTAMP')];

$sql = $builder->setData($data)->updateFields($additionalUpdateField, true)->upsertBatch();
/* MySQLi produces:
    INSERT INTO `db_user` (`country`, `email`, `name`)
    VALUES ('Iran','ahmadinejad@example.com','Ahmadinejad'),('El Salvador','pedro@example.com','Pedro')
    ON DUPLICATE KEY UPDATE
    `country` = VALUES(`country`),
    `email` = VALUES(`email`),
    `name` = VALUES(`name`),
    `updated_at` = CURRENT_TIMESTAMP
*/

请注意, updated_at 字段未插入但用于更新。

更新数据

Update

$builder->replace()

这将执行一个 REPLACE 语句,基本上是可选的 DELETE + INSERT 的 SQL标准,使用 PRIMARYUNIQUE 键作为确定因素。 在我们的例子中,它将省去你需要实现 select()、update()、delete() 和 insert() 调用的不同组合的复杂逻辑的需要。

例如:

<?php

$data = [
    'title' => 'My title',
    'name'  => 'My Name',
    'date'  => 'My date',
];

$builder->replace($data);
// Executes: REPLACE INTO mytable (title, name, date) VALUES ('My title', 'My name', 'My date')

在上面的示例中,如果我们假设 title 字段是我们的主键,则如果一行包含 My title 作为 title 值,则会删除该行,并用我们的新行数据替换它。

也允许使用 set() 方法,所有值都会自动转义,就像 insert() 一样。

$builder->set()

此方法使你可以为以后通过 insert()update() 方法传入的插入或更新设置值。

它可以代替直接将数据数组传递给 insert() 或 update() 方法:

<?php

$builder->set('name', $name);
$builder->insert();
// Produces: INSERT INTO mytable (`name`) VALUES ('{$name}')

如果使用多个方法调用,它们将根据你执行插入还是更新来正确组装:

<?php

$builder->set('name', $name);
$builder->set('title', $title);
$builder->set('status', $status);
$builder->insert();

set() 也将接受一个可选的第三个参数($escape),如果设置为 false 将阻止对值进行转义。为了说明差异,这里 set() 同时使用和不使用 escape 参数的示例。

<?php

$builder->set('field', 'field+1', false);
$builder->where('id', 2);
$builder->update();
// gives UPDATE mytable SET field = field+1 WHERE `id` = 2

$builder->set('field', 'field+1');
$builder->where('id', 2);
$builder->update();
// gives UPDATE `mytable` SET `field` = 'field+1' WHERE `id` = 2

你也可以向此方法传递关联数组:

<?php

$array = [
    'name'   => $name,
    'title'  => $title,
    'status' => $status,
];

$builder->set($array);
$builder->insert();

或者一个对象:

<?php

class Myclass
{
    public $title   = 'My Title';
    public $content = 'My Content';
    public $date    = 'My Date';
}

$object = new Myclass();
$builder->set($object);
$builder->insert();

$builder->update()

根据你提供的数据生成 update 字符串并运行查询。你可以将一个**数组**或**对象**传递给该方法。下面是一个使用数组的示例:

<?php

$data = [
    'title' => $title,
    'name'  => $name,
    'date'  => $date,
];

$builder->where('id', $id);
$builder->update($data);
/*
 * Produces:
 * UPDATE mytable
 * SET title = '{$title}', name = '{$name}', date = '{$date}'
 * WHERE id = $id
 */

或者你可以提供一个对象:

<?php

class Myclass
{
    public $title   = 'My Title';
    public $content = 'My Content';
    public $date    = 'My Date';
}

$object = new Myclass();
$builder->where('id', $id);
$builder->update($object);
/*
 * Produces:
 * UPDATE `mytable`
 * SET `title` = '{$title}', `name` = '{$name}', `date` = '{$date}'
 * WHERE id = `$id`
 */

备注

RawSql 外,所有值都会自动转义,生成更安全的查询。

警告

当你使用 RawSql 时,必须手动对数据进行转义。否则可能会导致 SQL 注入。

你会注意到使用了 $builder->where() 方法,使你可以设置 WHERE 子句。 你可以选择直接将此信息作为字符串传递给 update() 方法:

<?php

$builder->update($data, 'id = 4');

或者作为数组:

<?php

$builder->update($data, ['id' => $id]);

你也可以在执行更新时使用上面描述的 $builder->set() 方法。

UpdateBatch

$builder->updateBatch()

备注

从 v4.3.0 开始, updateBatch() 的第二个参数 $index 改为 $constraints。它现在接受数组、字符串或 RawSql 类型。

根据你提供的数据生成 update 字符串,并运行查询。你可以将一个**数组**或**对象**传递给该方法。下面是一个使用数组的示例:

<?php

$data = [
    [
        'title'  => 'Title 1',
        'author' => 'Author 1',
        'name'   => 'Name 1',
        'date'   => 'Date 1',
    ],
    [
        'title'  => 'Title 2',
        'author' => 'Author 2',
        'name'   => 'Name 2',
        'date'   => 'Date 2',
    ],
];
$builder->updateBatch($data, ['title', 'author']);
/*
 * Produces:
 * UPDATE `mytable`
 * INNER JOIN (
 * SELECT 'Title 1' `title`, 'Author 1' `author`, 'Name 1' `name`, 'Date 1' `date` UNION ALL
 * SELECT 'Title 2' `title`, 'Author 2' `author`, 'Name 2' `name`, 'Date 2' `date`
 * ) `u`
 * ON `mytable`.`title` = `u`.`title` AND `mytable`.`author` = `u`.`author`
 * SET
 * `mytable`.`title` = `u`.`title`,
 * `mytable`.`name` = `u`.`name`,
 * `mytable`.`date` = `u`.`date`
 */

备注

从 v4.3.0 开始,生成的 SQL 结构得到了改进。

第一个参数是一个关联数组,第二个参数是 where 键。

从 v4.3.0 开始,你也可以使用 setQueryAsData()onConstraint()updateFields() 方法:

<?php

use CodeIgniter\Database\RawSql;

$builder->setData($data)->onConstraint('title, author')->updateBatch();

// OR
$builder->setData($data, null, 'u')
    ->onConstraint(['`mytable`.`title`' => '`u`.`title`', 'author' => new RawSql('`u`.`author`')])
    ->updateBatch();

// OR
foreach ($data as $row) {
    $builder->setData($row);
}
$builder->onConstraint('title, author')->updateBatch();

// OR
$builder->setData($data, true, 'u')
    ->onConstraint(new RawSql('`mytable`.`title` = `u`.`title` AND `mytable`.`author` = `u`.`author`'))
    ->updateFields(['last_update' => new RawSql('CURRENT_TIMESTAMP()')], true)
    ->updateBatch();
/*
 * Produces:
 * UPDATE `mytable`
 * INNER JOIN (
 * SELECT 'Title 1' `title`, 'Author 1' `author`, 'Name 1' `name`, 'Date 1' `date` UNION ALL
 * SELECT 'Title 2' `title`, 'Author 2' `author`, 'Name 2' `name`, 'Date 2' `date`
 * ) `u`
 * ON `mytable`.`title` = `u`.`title` AND `mytable`.`author` = `u`.`author`
 * SET
 * `mytable`.`title` = `u`.`title`,
 * `mytable`.`name` = `u`.`name`,
 * `mytable`.`date` = `u`.`date`,
 * `mytable`.`last_update` = CURRENT_TIMESTAMP() // this only applies to the last scenario
 */

备注

RawSql 外,所有值都会自动转义,生成更安全的查询。

警告

当你使用 RawSql 时,必须手动对数据进行转义。否则可能会导致 SQL 注入。

备注

由于这项工作的性质,此方法无法为 affectedRows() 提供适当的结果。 相反, updateBatch() 返回受影响的行数。

你也可以从查询中更新:

<?php

$query = $this->db->table('user2')
    ->select('user2.name, user2.email, user2.country')
    ->join('user', 'user.email = user2.email', 'inner')
    ->where('user2.country', 'US');

$additionalUpdateField = ['updated_at' => new RawSql('CURRENT_TIMESTAMP')];

$sql = $builder->table('user')
    ->setQueryAsData($query, null, 'u')
    ->onConstraint('email')
    ->updateFields($additionalUpdateField, true)
    ->updateBatch();
/*
 * Produces:
 * UPDATE `user`
 * INNER JOIN (
 * SELECT user2.name, user2.email, user2.country
 * FROM user2
 * INNER JOIN user ON user.email = user2.email
 * WHERE user2.country = 'US'
 * ) `u`
 * ON `user`.`email` = `u`.`email`
 * SET
 * `mytable`.`name` = `u`.`name`,
 * `mytable`.`email` = `u`.`email`,
 * `mytable`.`country` = `u`.`country`,
 * `mytable`.`updated_at` = CURRENT_TIMESTAMP()
 */

备注

可以从 v4.3.0 开始使用 setQueryAsData()onConstraint()updateFields() 方法。

备注

必须将选择查询的列别名为目标表的列名。

$builder->getCompiledUpdate()

此方法的工作方式与 $builder->getCompiledInsert() 完全相同,只是它生成 UPDATE SQL 字符串而不是 INSERT SQL 字符串。

有关更多信息,请查看 $builder->getCompiledInsert() 的文档。

备注

此方法不适用于批量更新。

删除数据

Delete

$builder->delete()

生成 DELETE SQL 字符串并运行查询。

<?php

$builder->delete(['id' => $id]);
// Produces: DELETE FROM mytable WHERE id = $id

第一个参数是 where 子句。 你也可以使用 where()orWhere() 方法,而不是将数据传递给方法的第一个参数:

<?php

$builder->where('id', $id);
$builder->delete();
/*
 * Produces:
 * DELETE FROM mytable
 * WHERE id = $id
 */

如果要从表中删除所有数据,可以使用 truncate() 方法或 emptyTable()

$builder->deleteBatch()

4.3.0 新版功能.

根据一组数据生成批量 DELETE 语句。

<?php

$data = [
    [
        'order'   => 48372,
        'line'    => 3,
        'product' => 'Keyboard',
        'qty'     => 1,
    ],
    [
        'order'   => 48372,
        'line'    => 4,
        'product' => 'Mouse',
        'qty'     => 1,
    ],
    [
        'order'   => 48372,
        'line'    => 5,
        'product' => 'Monitor',
        'qty'     => 2,
    ],
];

$builder->setData($data, true, 'del')
    ->onConstraint('order, line')
    ->where('del.qty >', 1)
    ->deleteBatch();

/*
 * MySQL Produces:
 * DELETE `order_line` FROM `order_line`
 * INNER JOIN (
 * SELECT 3 `line`, 48372 `order`, 'Keyboard' `product`, 1 `qty` UNION ALL
 * SELECT 4 `line`, 48372 `order`, 'Mouse'    `product`, 1 `qty` UNION ALL
 * SELECT 5 `line`, 48372 `order`, 'Monitor'  `product`, 2 `qty`
 * ) `del`
 * ON `order_line`.`order` = `del`.`order` AND `order_line`.`line` = `del`.`line`
 * WHERE `del`.`qty` > 1
 */

当在具有复合主键的表中删除数据时,此方法特别有用。

备注

SQLite 不支持使用 where()

你也可以从查询中删除:

<?php

use CodeIgniter\Database\RawSql;

$query = $this->db->table('user2')->select('email, name, country')->where('country', 'Greece');

$this->db->table('user')
    ->setQueryAsData($query, 'alias')
    ->onConstraint('email')
    ->where('alias.name = user.name')
    ->deleteBatch();

/* MySQLi produces:
    DELETE `user` FROM `user`
    INNER JOIN (
    SELECT `email`, `name`, `country`
    FROM `user2`
    WHERE `country` = 'Greece') `alias`
    ON `user`.`email` = `alias`.`email`
    WHERE `alias`.`name` = `user`.`name`
*/

备注

可以从 v4.3.0 开始使用 deleteBatch()

$builder->emptyTable()

生成 DELETE SQL 字符串并运行查询:

<?php

$builder->emptyTable('mytable');
// Produces: DELETE FROM mytable

$builder->truncate()

生成 TRUNCATE SQL 字符串并运行查询。

<?php

$builder->truncate();
/*
 * Produce:
 * TRUNCATE mytable
 */

备注

如果不可用 TRUNCATE 命令, truncate() 将使用 DELETE FROM table

$builder->getCompiledDelete()

此方法的工作方式与 $builder->getCompiledInsert() 完全相同,只是它生成 DELETE SQL字符串而不是 INSERT SQL字符串。

有关更多信息,请查看 $builder->getCompiledInsert() 的文档。

条件语句

When

$builder->when()

4.3.0 新版功能.

这允许基于条件修改查询,而不会打破查询构建器链。第一个参数是条件,它应该评估为布尔值。第二个参数是可调用的,它将在条件为 true 时运行。

例如,你可能只想应用给定的 WHERE 语句基于 HTTP 请求中发送的值:

<?php

$status = service('request')->getPost('status');

$users = $this->db->table('users')
    ->when($status, static function ($query, $status) {
        $query->where('status', $status);
    })
    ->get();

由于条件评估为 true,所以可调用的将被调用。条件中设置的值将作为第二个参数传递给可调用的,以便可以在查询中使用它。

有时你可能希望在条件评估为 false 时应用不同的语句。这可以通过提供第二个闭包来实现:

<?php

$onlyInactive = service('request')->getPost('return_inactive');

$users = $this->db->table('users')
    ->when($onlyInactive, static function ($query, $onlyInactive) {
        $query->where('status', 'inactive');
    }, static function ($query) {
        $query->where('status', 'active');
    })
    ->get();

WhenNot

$builder->whenNot()

4.3.0 新版功能.

这与 $builder->when() 的工作方式完全相同,只是它只有在条件评估为 false 时才会运行可调用的,而不是像 when() 中的 true

<?php

$status = service('request')->getPost('status');

$users = $this->db->table('users')
    ->whenNot($status, static function ($query, $status) {
        $query->where('active', 0);
    })
    ->get();

方法链

方法链允许你通过连接多个方法来简化语法。考虑这个例子:

<?php

$query = $builder->select('title')
    ->where('id', $id)
    ->limit(10, 20)
    ->get();

重置查询构建器

ResetQuery

$builder->resetQuery()

重置查询构建器允许你在不先使用 $builder->get()$builder->insert() 等方法执行查询的情况下重新开始查询。

当你使用查询构建器生成 SQL(例如 $builder->getCompiledSelect()),然后选择运行查询时,这很有用:

<?php

// Note that the parameter of the `getCompiledSelect()` method is false
$sql = $builder->select(['field1', 'field2'])
    ->where('field3', 5)
    ->getCompiledSelect(false);

// ...
// Do something crazy with the SQL code... like add it to a cron script for
// later execution or something...
// ...

$data = $builder->get()->getResultArray();
/*
 * Would execute and return an array of results of the following query:
 * SELECT field1, field2 FROM mytable WHERE field3 = 5;
 */

类参考

class CodeIgniter\Database\BaseBuilder
db()
返回

正在使用的数据库连接

返回类型

ConnectionInterface

$db 返回当前数据库连接。用于访问查询构建器无法直接使用的 ConnectionInterface 方法,如 insertID()errors()

resetQuery()
返回

BaseBuilder 实例(方法链)

返回类型

BaseBuilder

重置当前的查询构建器状态。当你想要构建可在某些条件下取消的查询时很有用。

countAllResults([$reset = true])
参数
  • $reset (bool) – 是否重置 SELECT 的值

返回

查询结果中的行数

返回类型

int

生成平台特定的查询字符串,用于统计查询构建器查询返回的所有记录。

countAll([$reset = true])
参数
  • $reset (bool) – 是否重置 SELECT 的值

返回

查询结果中的行数

返回类型

int

生成平台特定的查询字符串,用于统计特定表中的所有记录。

get([$limit = null[, $offset = null[, $reset = true]]]])
参数
  • $limit (int) – LIMIT 子句

  • $offset (int) – OFFSET 子句

  • $reset (bool) – 是否要清除查询构建器的值?

返回

\CodeIgniter\Database\ResultInterface 实例(方法链)

返回类型

\CodeIgniter\Database\ResultInterface

编译并运行基于已经调用的查询构建器方法的 SELECT 语句。

getWhere([$where = null[, $limit = null[, $offset = null[, $reset = true]]]]])
参数
  • $where (string) – WHERE 子句

  • $limit (int) – LIMIT 子句

  • $offset (int) – OFFSET 子句

  • $reset (bool) – 是否要清除查询构建器的值?

返回

\CodeIgniter\Database\ResultInterface 实例(方法链)

返回类型

\CodeIgniter\Database\ResultInterface

get() 相同,但也允许直接添加 WHERE。

select([$select = '*'[, $escape = null]])
参数
  • $select (array|RawSql|string) – 查询的 SELECT 部分

  • $escape (bool) – 是否转义值和标识符

返回

BaseBuilder 实例(方法链)

返回类型

BaseBuilder

向查询添加 SELECT 子句。

selectAvg([$select = ''[, $alias = '']])
参数
  • $select (string) – 要计算平均值的字段

  • $alias (string) – 结果值名称的别名

返回

BaseBuilder 实例(方法链)

返回类型

BaseBuilder

向查询添加 SELECT AVG(field) 子句。

selectMax([$select = ''[, $alias = '']])
参数
  • $select (string) – 要计算最大值的字段

  • $alias (string) – 结果值名称的别名

返回

BaseBuilder 实例(方法链)

返回类型

BaseBuilder

向查询添加 SELECT MAX(field) 子句。

selectMin([$select = ''[, $alias = '']])
参数
  • $select (string) – 要计算最小值的字段

  • $alias (string) – 结果值名称的别名

返回

BaseBuilder 实例(方法链)

返回类型

BaseBuilder

向查询添加 SELECT MIN(field) 子句。

selectSum([$select = ''[, $alias = '']])
参数
  • $select (string) – 要计算总和的字段

  • $alias (string) – 结果值名称的别名

返回

BaseBuilder 实例(方法链)

返回类型

BaseBuilder

向查询添加 SELECT SUM(field) 子句。

selectCount([$select = ''[, $alias = '']])
参数
  • $select (string) – 要计算平均值的字段

  • $alias (string) – 结果值名称的别名

返回

BaseBuilder 实例(方法链)

返回类型

BaseBuilder

向查询添加 SELECT COUNT(field) 子句。

selectSubquery(BaseBuilder $subquery, string $as)
参数
  • $subquery (string) – BaseBuilder 的实例

  • $as (string) – 结果值名称的别名

返回

BaseBuilder 实例(方法链)

返回类型

BaseBuilder

向选择添加子查询

distinct([$val = true])
参数
  • $val (bool) – “distinct” 标志的期望值

返回

BaseBuilder 实例(方法链)

返回类型

BaseBuilder

设置一个标志,告诉查询构建器向查询的 SELECT 部分添加 DISTINCT 子句。

from($from[, $overwrite = false])
参数
  • $from (mixed) – 表名(字符串或数组)

  • $overwrite (bool) – 是否删除第一个已存在的表?

返回

BaseBuilder 实例(方法链)

返回类型

BaseBuilder

指定查询的 FROM 子句。

fromSubquery($from, $alias)
参数
  • $from (BaseBuilder) – BaseBuilder 类的实例

  • $alias (string) – 子查询的别名

返回

BaseBuilder 实例(方法链)

返回类型

BaseBuilder

使用子查询指定查询的 FROM 子句。

setQueryAsData($query[, $alias[, $columns = null]])

4.3.0 新版功能.

参数
  • $query (BaseBuilder|RawSql) – BaseBuilder 或 RawSql 的实例

  • $alias (string|null) – 查询的别名

  • $columns (array|string|null) – 查询中的列,以数组或逗号分隔的字符串表示

返回

BaseBuilder 实例(方法链)

返回类型

BaseBuilder

insertBatch()updateBatch()upsertBatch() 设置查询作为数据源。 如果 $columns 为 null,则会运行查询来生成列名。

join($table, $cond[, $type = ''[, $escape = null]])
参数
  • $table (string) – 要连接的表名

  • $cond (string) – JOIN ON 条件

  • $type (string) – JOIN 类型

  • $escape (bool) – 是否转义值和标识符

返回

BaseBuilder 实例(方法链)

返回类型

BaseBuilder

向查询添加 JOIN 子句。

where($key[, $value = null[, $escape = null]])
参数
  • $key (array|RawSql|string) – 要比较的字段名称,或关联数组

  • $value (mixed) – 如果是单个键,则与此值进行比较

  • $escape (bool) – 是否转义值和标识符

返回

BaseBuilder 实例(方法链)

返回类型

BaseBuilder

生成查询的 WHERE 部分。使用 AND 分隔多个调用。

orWhere($key[, $value = null[, $escape = null]])
参数
  • $key (mixed) – 要比较的字段名称,或关联数组

  • $value (mixed) – 如果是单个键,则与此值进行比较

  • $escape (bool) – 是否转义值和标识符

返回

BaseBuilder 实例(方法链)

返回类型

BaseBuilder

生成查询的 WHERE 部分。使用 OR 分隔多个调用。

orWhereIn([$key = null[, $values = null[, $escape = null]]])
参数
  • $key (string) – 要搜索的字段

  • $values (array|BaseBulder|Closure) – 目标值的数组,或子查询的匿名函数

  • $escape (bool) – 是否转义值和标识符

返回

BaseBuilder 实例(方法链)

返回类型

BaseBuilder

生成 WHERE 字段 IN('item', 'item') SQL 查询,如果适用的话,使用 OR 连接。

orWhereNotIn([$key = null[, $values = null[, $escape = null]]])
参数
  • $key (string) – 要搜索的字段

  • $values (array|BaseBulder|Closure) – 目标值的数组,或子查询的匿名函数

  • $escape (bool) – 是否转义值和标识符

返回

BaseBuilder 实例(方法链)

返回类型

BaseBuilder

生成 WHERE 字段 NOT IN('item', 'item') SQL 查询,如果适用的话,使用 OR 连接。

whereIn([$key = null[, $values = null[, $escape = null]]])
参数
  • $key (string) – 要检查的字段名称

  • $values (array|BaseBulder|Closure) – 目标值的数组,或子查询的匿名函数

  • $escape (bool) – 是否转义值和标识符

返回

BaseBuilder 实例(方法链)

返回类型

BaseBuilder

生成 WHERE 字段 IN('item', 'item') SQL 查询,如果适用的话,使用 AND 连接。

whereNotIn([$key = null[, $values = null[, $escape = null]]])
参数
  • $key (string) – 要检查的字段名称

  • $values (array|BaseBulder|Closure) – 目标值的数组,或子查询的匿名函数

  • $escape (bool) – 是否转义值和标识符

返回

BaseBuilder 实例(方法链)

返回类型

BaseBuilder

生成 WHERE 字段 NOT IN('item', 'item') SQL 查询,如果适用的话,使用 AND 连接。

groupStart()
返回

BaseBuilder 实例(方法链)

返回类型

BaseBuilder

启动一个组表达式,对表达式内的条件使用 AND 连接。

orGroupStart()
返回

BaseBuilder 实例(方法链)

返回类型

BaseBuilder

启动一个组表达式,对表达式内的条件使用 OR 连接。

notGroupStart()
返回

BaseBuilder 实例(方法链)

返回类型

BaseBuilder

启动一个组表达式,对表达式内的条件使用 AND NOT 连接。

orNotGroupStart()
返回

BaseBuilder 实例(方法链)

返回类型

BaseBuilder

启动一个组表达式,对表达式内的条件使用 OR NOT 连接。

groupEnd()
返回

BaseBuilder 实例(方法链)

返回类型

BaseBuilder

结束一个组表达式。

like($field[, $match = ''[, $side = 'both'[, $escape = null[, $insensitiveSearch = false]]]])
参数
  • $field (array|RawSql|string) – 字段名称

  • $match (string) – 要匹配的文本部分

  • $side (string) – 在表达式的哪一侧放置 ‘%’ 通配符

  • $escape (bool) – 是否转义值和标识符

  • $insensitiveSearch (bool) – 是否强制执行不区分大小写的搜索

返回

BaseBuilder 实例(方法链)

返回类型

BaseBuilder

向查询添加 LIKE 子句,使用 AND 分隔多个调用。

orLike($field[, $match = ''[, $side = 'both'[, $escape = null[, $insensitiveSearch = false]]]])
参数
  • $field (string) – 字段名称

  • $match (string) – 要匹配的文本部分

  • $side (string) – 在表达式的哪一侧放置 ‘%’ 通配符

  • $escape (bool) – 是否转义值和标识符

  • $insensitiveSearch (bool) – 是否强制执行不区分大小写的搜索

返回

BaseBuilder 实例(方法链)

返回类型

BaseBuilder

向查询添加 LIKE 子句,使用 OR 分隔多个调用。

notLike($field[, $match = ''[, $side = 'both'[, $escape = null[, $insensitiveSearch = false]]]])
参数
  • $field (string) – 字段名称

  • $match (string) – 要匹配的文本部分

  • $side (string) – 在表达式的哪一侧放置 ‘%’ 通配符

  • $escape (bool) – 是否转义值和标识符

  • $insensitiveSearch (bool) – 是否强制执行不区分大小写的搜索

返回

BaseBuilder 实例(方法链)

返回类型

BaseBuilder

向查询添加 NOT LIKE 子句,使用 AND 分隔多个调用。

orNotLike($field[, $match = ''[, $side = 'both'[, $escape = null[, $insensitiveSearch = false]]]])
参数
  • $field (string) – 字段名称

  • $match (string) – 要匹配的文本部分

  • $side (string) – 在表达式的哪一侧放置 ‘%’ 通配符

  • $escape (bool) – 是否转义值和标识符

  • $insensitiveSearch (bool) – 是否强制执行不区分大小写的搜索

返回

BaseBuilder 实例(方法链)

返回类型

BaseBuilder

向查询添加 NOT LIKE 子句,使用 OR 分隔多个调用。

having($key[, $value = null[, $escape = null]])
参数
  • $key (mixed) – 标识符(字符串)或字段/值对的关联数组

  • $value (string) – 如果 $key 是标识符,则查找此值

  • $escape (string) – 是否转义值和标识符

返回

BaseBuilder 实例(方法链)

返回类型

BaseBuilder

向查询添加 HAVING 子句,使用 AND 分隔多个调用。

orHaving($key[, $value = null[, $escape = null]])
参数
  • $key (mixed) – 标识符(字符串)或字段/值对的关联数组

  • $value (string) – 如果 $key 是标识符,则查找此值

  • $escape (string) – 是否转义值和标识符

返回

BaseBuilder 实例(方法链)

返回类型

BaseBuilder

向查询添加 HAVING 子句,使用 OR 分隔多个调用。

orHavingIn([$key = null[, $values = null[, $escape = null]]])
参数
  • $key (string) – 要搜索的字段

  • $values (array|BaseBulder|Closure) – 目标值的数组或子查询的匿名函数

  • $escape (bool) – 是否转义值和标识符

返回

BaseBuilder 实例(方法链)

返回类型

BaseBuilder

生成 HAVING 字段 IN('item', 'item') SQL查询,如果适用的话,使用 OR 连接。

orHavingNotIn([$key = null[, $values = null[, $escape = null]]])
参数
  • $key (string) – 要搜索的字段

  • $values (array|BaseBulder|Closure) – 目标值的数组或子查询的匿名函数

  • $escape (bool) – 是否转义值和标识符

返回

BaseBuilder 实例(方法链)

返回类型

BaseBuilder

生成 HAVING 字段 NOT IN('item', 'item') SQL查询,如果适用的话,使用 OR 连接。

havingIn([$key = null[, $values = null[, $escape = null]]])
参数
  • $key (string) – 要检查的字段名称

  • $values (array|BaseBulder|Closure) – 目标值的数组或子查询的匿名函数

  • $escape (bool) – 是否转义值和标识符

返回

BaseBuilder 实例(方法链)

返回类型

BaseBuilder

生成 HAVING 字段 IN('item', 'item') SQL查询,如果适用的话,使用 AND 连接。

havingNotIn([$key = null[, $values = null[, $escape = null]]])
参数
  • $key (string) – 要检查的字段名称

  • $values (array|BaseBulder|Closure) – 目标值的数组或子查询的匿名函数

  • $escape (bool) – 是否转义值和标识符

  • $insensitiveSearch (bool) – 是否强制执行不区分大小写的搜索

返回

BaseBuilder 实例(方法链)

返回类型

BaseBuilder

生成 HAVING 字段 NOT IN('item', 'item') SQL查询,如果适用的话,使用 AND 连接。

havingLike($field[, $match = ''[, $side = 'both'[, $escape = null[, $insensitiveSearch = false]]]])
参数
  • $field (string) – 字段名称

  • $match (string) – 要匹配的文本部分

  • $side (string) – 在表达式的哪一侧放置 ‘%’ 通配符

  • $escape (bool) – 是否转义值和标识符

  • $insensitiveSearch (bool) – 是否强制执行不区分大小写的搜索

返回

BaseBuilder 实例(方法链)

返回类型

BaseBuilder

HAVING 部分添加 LIKE 子句,使用 AND 分隔多个调用。

orHavingLike($field[, $match = ''[, $side = 'both'[, $escape = null[, $insensitiveSearch = false]]]])
参数
  • $field (string) – 字段名称

  • $match (string) – 要匹配的文本部分

  • $side (string) – 在表达式的哪一侧放置 ‘%’ 通配符

  • $escape (bool) – 是否转义值和标识符

  • $insensitiveSearch (bool) – 是否强制执行不区分大小写的搜索

返回

BaseBuilder 实例(方法链)

返回类型

BaseBuilder

HAVING 部分添加 LIKE 子句,使用 OR 分隔多个调用。

notHavingLike($field[, $match = ''[, $side = 'both'[, $escape = null[, $insensitiveSearch = false]]]])
参数
  • $field (string) – 字段名称

  • $match (string) – 要匹配的文本部分

  • $side (string) – 在表达式的哪一侧放置 ‘%’ 通配符

  • $escape (bool) – 是否转义值和标识符

  • $insensitiveSearch (bool) – 是否强制执行不区分大小写的搜索

返回

BaseBuilder 实例(方法链)

返回类型

BaseBuilder

HAVING 部分添加 NOT LIKE 子句,使用 AND 分隔多个调用。

orNotHavingLike($field[, $match = ''[, $side = 'both'[, $escape = null[, $insensitiveSearch = false]]]])
参数
  • $field (string) – 字段名称

  • $match (string) – 要匹配的文本部分

  • $side (string) – 在表达式的哪一侧放置 ‘%’ 通配符

  • $escape (bool) – 是否转义值和标识符

返回

BaseBuilder 实例(方法链)

返回类型

BaseBuilder

HAVING 部分添加 NOT LIKE 子句,使用 OR 分隔多个调用。

havingGroupStart()
返回

BaseBuilder 实例(方法链)

返回类型

BaseBuilder

启动 HAVING 子句的一个组表达式,对表达式内的条件使用 AND 连接。

orHavingGroupStart()
返回

BaseBuilder 实例(方法链)

返回类型

BaseBuilder

启动 HAVING 子句的一个组表达式,对表达式内的条件使用 OR 连接。

notHavingGroupStart()
返回

BaseBuilder 实例(方法链)

返回类型

BaseBuilder

启动 HAVING 子句的一个组表达式,对表达式内的条件使用 AND NOT 连接。

orNotHavingGroupStart()
返回

BaseBuilder 实例(方法链)

返回类型

BaseBuilder

启动 HAVING 子句的一个组表达式,对表达式内的条件使用 OR NOT 连接。

havingGroupEnd()
返回

BaseBuilder 实例(方法链)

返回类型

BaseBuilder

结束 HAVING 子句的一个组表达式。

groupBy($by[, $escape = null])
参数
  • $by (mixed) – 要分组的字段;字符串或数组

返回

BaseBuilder 实例(方法链)

返回类型

BaseBuilder

向查询添加 GROUP BY 子句。

orderBy($orderby[, $direction = ''[, $escape = null]])
参数
  • $orderby (string) – 要排序的字段

  • $direction (string) – 请求的排序方向 - ASC、DESC 或 random

  • $escape (bool) – 是否转义值和标识符

返回

BaseBuilder 实例(方法链)

返回类型

BaseBuilder

向查询添加 ORDER BY 子句。

limit($value[, $offset = 0])
参数
  • $value (int) – 要限制结果的行数

  • $offset (int) – 要跳过的行数

返回

BaseBuilder 实例(方法链)

返回类型

BaseBuilder

向查询添加 LIMITOFFSET 子句。

offset($offset)
参数
  • $offset (int) – 要跳过的行数

返回

BaseBuilder 实例(方法链)

返回类型

BaseBuilder

向查询添加 OFFSET 子句。

union($union)
参数
  • $union (BaseBulder|Closure) – 联合查询

返回

BaseBuilder 实例(方法链)

返回类型

BaseBuilder

添加 UNION 子句。

unionAll($union)
参数
  • $union (BaseBulder|Closure) – 联合查询

返回

BaseBuilder 实例(方法链)

返回类型

BaseBuilder

添加 UNION ALL 子句。

set($key[, $value = ''[, $escape = null]])
参数
  • $key (mixed) – 字段名称,或字段/值对的数组

  • $value (mixed) – 如果 $key 是单个字段,则为字段值

  • $escape (bool) – 是否转义值

返回

BaseBuilder 实例(方法链)

返回类型

BaseBuilder

添加通过 insert()update()replace() 稍后传入的字段/值对。

insert([$set = null[, $escape = null]])
参数
  • $set (array) – 字段/值对的关联数组

  • $escape (bool) – 是否转义值

返回

成功则为 true,失败则为 false

返回类型

bool

编译并执行 INSERT 语句。

insertBatch([$set = null[, $escape = null[, $batch_size = 100]]])
参数
  • $set (array) – 要插入的数据

  • $escape (bool) – 是否转义值

  • $batch_size (int) – 一次插入的行数

返回

插入的行数,失败则为 false

返回类型

int|false

编译并执行批量 INSERT 语句。

备注

当提供多于 $batch_size 行时,会执行多个 INSERT 查询,每个试图插入最多 $batch_size 行。

setInsertBatch($key[, $value = ''[, $escape = null]])

4.3.0 版后已移除: 请使用 CodeIgniter\Database\BaseBuilder::setData() 替代。

参数
  • $key (mixed) – 字段名称或字段/值对数组

  • $value (string) – 如果 $key 是单个字段,则为字段值

  • $escape (bool) – 是否转义值

返回

BaseBuilder 实例(方法链)

返回类型

BaseBuilder

添加后面通过 insertBatch() 批量插入到表中的字段/值对。

重要

此方法不建议使用。将在未来版本中删除。

upsert([$set = null[, $escape = null]])
参数
  • $set (array) – 字段/值对的关联数组

  • $escape (bool) – 是否转义值

返回

成功则为 true,失败则为 false

返回类型

bool

编译并执行 UPSERT 语句。

upsertBatch([$set = null[, $escape = null[, $batch_size = 100]]])
参数
  • $set (array) – 要插入更新的数据

  • $escape (bool) – 是否转义值

  • $batch_size (int) – 一次插入更新的行数

返回

插入更新的行数,失败则为 false

返回类型

int|false

编译并执行批量 UPSERT 语句。

备注

MySQL 使用 ON DUPLICATE KEY UPDATE,每行的 affected-rows 值 如果行作为新行插入,则为 1;如果更新了现有行,则为 2;如果现有行设置为其当前值,则为 0。

备注

当提供多于 $batch_size 行时,会执行多个 UPSERT 查询,每个试图插入更新最多 $batch_size 行。

update([$set = null[, $where = null[, $limit = null]]])
参数
  • $set (array) – 字段/值对的关联数组

  • $where (string) – WHERE 子句

  • $limit (int) – LIMIT 子句

返回

成功则为 true,失败则为 false

返回类型

bool

编译并执行 UPDATE 语句。

updateBatch([$set = null[, $constraints = null[, $batchSize = 100]]])
参数
  • $set (array|object|null) – 字段名称,或字段/值对的关联数组

  • $constraints (array|RawSql|string|null) – 用作更新键的字段或字段集。

  • $batchSize (int) – 每个查询分组的条件数

返回

更新的行数,失败则为 false

返回类型

int|false

备注

从 v4.3.0 开始,参数 $set$constraints 的类型发生了变化。

编译并执行批量 UPDATE 语句。 $constraints 参数接受逗号分隔的列字符串,数组,关联数组或 RawSql

备注

当提供超过 $batchSize 个字段/值对时,将执行多个查询, 每个处理最多 $batchSize 个字段/值对。 如果我们将 $batchSize 设置为 0, 则所有字段/值对将在一个查询中执行。

updateFields($set[, $addToDefault = false[, $ignore = null]])

4.3.0 新版功能.

参数
  • $set (mixed) – 列的行或行数组,行是一个数组或对象

  • $addToDefault (bool) – 额外添加不在数据集中的列

  • $ignore (bool) – 忽略 $set 中的列数组

返回

BaseBuilder 实例(方法链)

返回类型

BaseBuilder

updateBatch()upsertBatch() 方法一起使用。 这定义了要更新的字段。

onConstraint($set)

4.3.0 新版功能.

参数
  • $set (mixed) – 用作键或约束的字段集或字段

返回

BaseBuilder 实例(方法链)

返回类型

BaseBuilder

updateBatch()upsertBatch() 方法一起使用。 这接受逗号分隔的列字符串,数组,关联数组或 RawSql。

setData($set[, $escape = null[, $alias = '']])

4.3.0 新版功能.

参数
  • $set (mixed) – 列的行或行数组,行是一个数组或对象

  • $escape (bool) – 是否转义值

  • $alias (bool) – 数据集的表别名

返回

BaseBuilder 实例(方法链)

返回类型

BaseBuilder

用于 *Batch() 方法为插入、更新、插入更新设置数据。

setUpdateBatch($key[, $value = ''[, $escape = null]])

4.3.0 版后已移除: 请使用 CodeIgniter\Database\BaseBuilder::setData() 替代。

参数
  • $key (mixed) – 字段名称或字段/值对数组

  • $value (string) – 如果 $key 是单个字段,则为字段值

  • $escape (bool) – 是否转义值

返回

BaseBuilder 实例(方法链)

返回类型

BaseBuilder

添加后面通过 updateBatch() 批量更新到表中的字段/值对。

重要

此方法不建议使用。将在未来版本中删除。

replace([$set = null])
参数
  • $set (array) – 字段/值对的关联数组

返回

成功则为 true,失败则为 false

返回类型

bool

编译并执行 REPLACE 语句。

delete([$where = ''[, $limit = null[, $reset_data = true]]])
参数
  • $where (string) – WHERE 子句

  • $limit (int) – LIMIT 子句

  • $reset_data (bool) – 是否重置查询的“写入”子句

返回

BaseBuilder 实例(方法链),失败则为 false

返回类型

BaseBuilder|false

编译并执行 DELETE 查询。

deleteBatch([$set = null[, $constraints = null[, $batchSize = 100]]])
参数
  • $set (array|object|null) – 字段名称,或字段/值对的关联数组

  • $constraints (array|RawSql|string|null) – 用作删除键的字段或字段集合

  • $batchSize (int) – 每个查询要分组的条件数

返回

删除的行数,失败则为 false

返回类型

int|false

编译并执行批量 DELETE 查询。

increment($column[, $value = 1])
参数
  • $column (string) – 要递增的列的名称

  • $value (int) – 要在列中递增的值

将字段的值递增指定的量。如果字段不是数值字段,比如 VARCHAR,它可能会被 $value 替换。

decrement($column[, $value = 1])
参数
  • $column (string) – 要递减的列的名称

  • $value (int) – 要在列中递减的值

将字段的值递减指定的量。如果字段不是数值字段,比如 VARCHAR,它可能会被 $value 替换。

truncate()
返回

成功则为 true,失败则为 false,测试模式下返回字符串

返回类型

bool|string

对表执行 TRUNCATE 语句。

备注

如果使用的数据库平台不支持 TRUNCATE, 将使用 DELETE FROM table 代替。

emptyTable()
返回

成功则为 true,失败则为 false

返回类型

bool

通过 DELETE 语句从表中删除所有记录。

getCompiledSelect([$reset = true])
参数
  • $reset (bool) – 是否重置当前的 QB 值

返回

编译后的 SQL 语句字符串

返回类型

string

编译 SELECT 语句并将其作为字符串返回。

getCompiledInsert([$reset = true])
参数
  • $reset (bool) – 是否重置当前的 QB 值

返回

编译后的 SQL 语句字符串

返回类型

string

编译 INSERT 语句并将其作为字符串返回。

getCompiledUpdate([$reset = true])
参数
  • $reset (bool) – 是否重置当前的 QB 值

返回

编译后的 SQL 语句字符串

返回类型

string

编译 UPDATE 语句并将其作为字符串返回。

getCompiledDelete([$reset = true])
参数
  • $reset (bool) – 是否重置当前的 QB 值

返回

编译后的 SQL 语句字符串

返回类型

string

编译 DELETE 语句并将其作为字符串返回。