查询构建器类

CodeIgniter 为你提供了访问查询构建器类的方式。该模式允许你通过最少的脚本执行数据库的检索、插入和更新操作。在某些情况下,只需一两行代码即可执行数据库操作。CodeIgniter 不要求每个数据库表对应一个独立的类文件,而是提供了一个更为简化的接口。

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

备注

CodeIgniter 不支持表名和列名中包含点号(.)。自 v4.5.0 起,支持包含点号的数据库名。

SQL 注入防护

你可以借助查询构建器相当安全地生成 SQL 语句。 然而,它并非被设计为无论你传递什么数据都能防止 SQL 注入。

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

  2. 它们的

  3. SQL 字符串 的一部分

查询构建器默认会对所有 进行转义。

默认情况下,它也会尝试正确保护 标识符SQL 字符串 中的标识符。然而,该实现是为了在多数用例中良好工作,并非设计用于防御所有攻击。因此,在未经适当验证的情况下,你绝不应将用户输入传递给它们。

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

加载查询构建器

查询构建器通过数据库连接上的 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

第一个参数(false)允许你设置查询构建器是否会被重置(因为参数的默认值为 true,即 getCompiledSelect(bool $reset = true),默认情况下会像使用 $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,导致 limit(10, 20) 保留在第二个查询中。

$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() 接受表示原始 SQL 字符串的 CodeIgniter\Database\RawSql 实例。

<?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

备注

如前所示,查询的 FROM 部分可以在 $db->table() 方法中指定。对 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() 接受表示原始 SQL 字符串的 CodeIgniter\Database\RawSql 实例作为 JOIN ON 条件。

<?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() 接受表示原始 SQL 字符串的 CodeIgniter\Database\RawSql 实例。

<?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()

生成 WHERE field IN (‘item’, ‘item’) SQL 查询,并在适当时通过 AND 连接:

<?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()

生成 WHERE field IN (‘item’, ‘item’) SQL 查询,并在适当时通过 OR 连接:

<?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()

生成 WHERE field NOT IN (‘item’, ‘item’) SQL 查询,并在适当时通过 AND 连接:

<?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()

生成 WHERE field NOT IN (‘item’, ‘item’) SQL 查询,并在适当时通过 OR 连接:

<?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 子句,适用于执行搜索。

备注

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

备注

所有 like* 方法变体可以通过将第五个参数设置为 true 来强制执行不区分大小写的搜索。这将使用平台特定的功能(如果可用),否则将强制将值转换为小写,即 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() 接受表示原始 SQL 字符串的 CodeIgniter\Database\RawSql 实例。

<?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 部分。有两种可能的语法,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

如果你使用的数据库由 CodeIgniter 转义值,可以通过传递可选的第三个参数并设置为 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()

生成 HAVING field IN (‘item’, ‘item’) SQL 查询,并在适当时通过 AND 连接:

<?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()

生成 HAVING field IN (‘item’, ‘item’) SQL 查询,并在适当时通过 OR 连接:

<?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()

生成 HAVING field NOT IN (‘item’, ‘item’) SQL 查询,并在适当时通过 AND 连接:

<?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()

生成 HAVING field NOT IN (‘item’, ‘item’) SQL 查询,并在适当时通过 OR 连接:

<?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 子句,适用于执行搜索。

备注

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

备注

所有 havingLike*() 方法变体可以通过将第五个参数设置为 true 来强制执行不区分大小写的搜索。这将使用平台特定的功能(如果可用),否则将强制将值转换为小写,即 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 子句。

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

第二个参数允许你设置结果的方向。选项为 ASCDESCRANDOM

<?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

备注

如果在 SQL 语句中指定了 LIMIT 0,将返回 0 条记录。然而,在查询构建器中存在一个错误:如果指定 limit(0),生成的 SQL 语句将没有 LIMIT 子句,并返回所有记录。在 v4.5.0 中添加了设置以修复此错误行为。详细信息请参阅 limit(0) 行为。此错误行为将在未来版本中修复,因此建议你更改默认设置。

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

<?php

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

$builder->countAllResults()

允许你确定特定查询构建器查询中的行数。查询支持查询构建器的限制条件,如 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() 方法的调用顺序如何。也就是说,即使在调用 union() 之后调用 limit()orderBy() 方法,这些方法也将相对于主查询。

在某些情况下,可能需要对查询结果进行排序或限制记录数。解决方案是使用通过 $db->newQuery() 创建的包装器。在下面的示例中,我们获取前 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())
*/

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

备注

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

警告

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

以下是使用对象的示例:

<?php

namespace App\Libraries;

class MyClass
{
    public $title   = 'My Title';
    public $content = 'My Content';
    public $date    = 'My Date';
}
<?php

use App\Libraries\MyClass;

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

第一个参数是一个对象。

$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
*/

备注

自 v4.3.0 起,可以使用 setQueryAsData()

备注

必须将 select 查询的列别名与目标表的列匹配。

更新插入数据

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

namespace App\Libraries;

class MyClass
{
    public $email   = 'ahmadinejad@example.com';
    public $name    = 'Ahmadinejad';
    public $country = 'Iran';
}
<?php

use App\Libraries\MyClass;

$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

use CodeIgniter\Database\RawSql;

$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
*/

备注

自 v4.3.0 起,可以使用 setQueryAsData()onConstraint()updateFields() 方法。

备注

必须将 select 查询的列别名与目标表的列匹配。

$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

use CodeIgniter\Database\RawSql;

$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 语句,本质上是 SQL 标准的(可选) DELETE + INSERT,使用 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() 方法传递数据数组:

<?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()

<?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

namespace App\Libraries;

class MyClass
{
    public $title   = 'My Title';
    public $content = 'My Content';
    public $date    = 'My Date';
}
<?php

use App\Libraries\MyClass;

$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

namespace App\Libraries;

class MyClass
{
    public $title   = 'My Title';
    public $content = 'My Content';
    public $date    = 'My Date';
}
<?php

use App\Libraries\MyClass;

$object = new MyClass();
$builder->where('id', $id);
$builder->update($object);
/*
 * Produces:
 * UPDATE `mytable`
 * SET `title` = '{$title}', `content` = '{$content}', `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() 方法。

$builder->getCompiledUpdate()

此方法与 $builder->getCompiledInsert() 的工作方式完全相同,区别在于生成的是 UPDATE SQL 字符串而非 INSERT SQL 字符串。

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

备注

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

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`
 */

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

备注

自 v4.3.0 起,生成的 SQL 结构已改进。

自 v4.3.0 起,你也可以使用 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() 返回受影响的行数。

从查询更新

自 v4.3.0 起,你也可以使用 setQueryAsData() 方法从查询更新:

<?php

use CodeIgniter\Database\RawSql;

$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()
 */

备注

必须将 select 查询的列别名与目标表的列匹配。

删除数据

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->getCompiledDelete()

此方法与 $builder->getCompiledInsert() 的工作方式完全相同,区别在于生成的是 DELETE SQL 字符串而非 INSERT SQL 字符串。

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

DeleteBatch

$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
 */

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

备注

SQLite3 不支持使用 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`
*/

$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”。

条件语句

When

$builder->when()

在 4.3.0 版本加入.

这允许根据条件修改查询,而不会中断查询构建器链。第一个参数是条件,应评估为布尔值。第二个参数是在条件为 true 时运行的回调函数。

例如,你可能希望仅根据 HTTP 请求中发送的值应用给定的 WHERE 语句:

<?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|RawSql) – JOIN ON 条件

  • $type (string) – JOIN 类型

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

返回:

BaseBuilder 实例(方法链)

返回类型:

BaseBuilder

向查询添加 JOIN 子句。自 v4.2.0 起,可以使用 RawSql 作为 JOIN ON 条件。另请参阅 $builder->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 field IN('item', 'item') SQL 查询,并在适当时用 OR 连接。

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

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

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

返回:

BaseBuilder 实例(方法链)

返回类型:

BaseBuilder

生成 WHERE field NOT IN('item', 'item') SQL 查询,并在适当时用 OR 连接。

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

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

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

返回:

BaseBuilder 实例(方法链)

返回类型:

BaseBuilder

生成 WHERE field IN('item', 'item') SQL 查询,并在适当时用 AND 连接。

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

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

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

返回:

BaseBuilder 实例(方法链)

返回类型:

BaseBuilder

生成 WHERE field 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) – 是否转义值和标识符

返回:

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 field IN('item', 'item') SQL 查询,并在适当时用 OR 连接。

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

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

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

返回:

BaseBuilder 实例(方法链)

返回类型:

BaseBuilder

生成 HAVING field NOT IN('item', 'item') SQL 查询,并在适当时用 OR 连接。

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

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

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

返回:

BaseBuilder 实例(方法链)

返回类型:

BaseBuilder

生成 HAVING field 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 field 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,每行的受影响行数为 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) – 要忽略的列数组

返回:

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) – 是否重置查询的 “write” 子句

返回:

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 语句。

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 语句并以字符串形式返回。