查询构建器类

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

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

备注

CodeIgniter 不支持表名和字段名中的点(.)。 从 v4.5.0 开始,支持带点的数据库名称。

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

下面第一个查询中的参数(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。 出现这种结果的原因是第一个查询中的参数设置为 falselimit(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

Added in version 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

备注

如前所示,查询的 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

Added in version 4.2.0.

从 v4.2.0 开始,$builder->join() 接受一个 CodeIgniter\Database\RawSql 实例作为 JOIN ON 条件,它表示原始 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

Added in version 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()

生成一个 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 '!'

如需控制通配符(%)的位置,可使用可选的第三个参数。选项包括 nonebeforeafter 以及 both (默认值)。

<?php

$builder->like('title', 'match', 'none');   // Produces: WHERE `title` LIKE 'match' ESCAPE '!'
$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

Added in version 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

如果使用的数据库由 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() 方法的调用顺序如何。 也就是说,limit()orderBy() 方法将相对于主查询,即使在 union() 之后调用也是如此。

在某些情况下,可能需要对查询结果进行排序或限制记录数。 解决方案是使用通过 $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 子句组。这样就可以创建具有复杂 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 子句添加右括号来结束当前分组。

插入数据

插入

$builder->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()

根据提供的数据生成插入忽略字符串并运行查询。如果已存在具有相同主键的条目,则不会插入该查询。 可以选择向方法传递 布尔值。也可以用于 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()

从数据插入

根据提供的数据生成插入字符串并运行查询。可以向方法传递 数组对象。以下是使用数组的示例:

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

备注

需要为选择查询的字段设置别名以匹配目标表的字段。

Upsert 数据

Upsert

$builder->upsert()

Added in version 4.3.0.

根据提供的数据生成 upsert 字符串并运行查询。可以向方法传递 数组对象。默认情况下,约束将按顺序定义。将首先选择主键,然后选择唯一键。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..

备注

对于 MySQL 之外的数据库,如果表有多个键(主键或唯一键), 在处理约束时默认将优先考虑主键。如果希望 使用不同的唯一键而不是主键,请使用 onConstraint() 方法。

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

以下是使用对象的示例:

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

Added in version 4.3.0.

$builder->upsert() 一样编译 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`)
*/

备注

此方法不适用于批量 upsert。

upsertBatch

$builder->upsertBatch()

Added in version 4.3.0.

从数据 Upsert

根据提供的数据生成 upsert 字符串并运行查询。可以向方法传递 数组对象。默认情况下,约束将按顺序定义。将首先选择主键,然后选择唯一键。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..

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

备注

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

从查询 Upsert

也可以从查询进行 upsert:

<?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() 方法。

备注

需要为选择查询的字段设置别名以匹配目标表的字段。

$builder->onConstraint()

Added in version 4.3.0.

允许手动设置用于 upsert 的约束。这不适用于 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()

Added in version 4.3.0.

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

<?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 字段未插入,但在更新时使用。

更新数据

更新

$builder->replace()

此方法执行 REPLACE 语句,这基本上是 SQL 标准中的(可选) DELETE + INSERT,使用 主键唯一键 作为决定条件。 在我们的情况下,它将使你无需实现复杂的 逻辑,无需使用 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 查询的字段设置别名以匹配目标表的字段。

删除数据

删除

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

Added in version 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()

Added in version 4.3.0.

这允许基于条件修改查询,而无需中断查询构建器链。第一个参数是条件,它使用 PHP 的原生布尔逻辑进行评估——这意味着像 falsenull0'0'0.0、空字符串 '' 和空数组 [] 这样的值将被视为 false。 第二个参数是在条件为 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()

Added in version 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]])

Added in version 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 字段 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) -- 要 upsert 的数据

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

  • $batch_size (int) -- 一次 upsert 的行数

返回:

upsert 的行数,失败时返回 false

返回类型:

int|false

编译并执行批量 UPSERT 语句。

备注

MySQL 使用 ON DUPLICATE KEY UPDATE,每行的受影响行数值 如果行作为新行插入则为 1,如果现有行被更新则为 2, 如果现有行被设置为其当前值则为 0。

备注

当提供超过 $batch_size 行时,将执行多个 UPSERT 查询,每个查询尝试 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]])

Added in version 4.3.0.

参数:
  • $set (mixed) -- 行或行数组,行是数组或对象

  • $addToDefault (bool) -- 添加比数据集中更多的字段

  • $ignore (bool) -- 从 $set 中忽略的字段数组

返回:

BaseBuilder 实例(方法链)

返回类型:

BaseBuilder

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

onConstraint($set)

Added in version 4.3.0.

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

返回:

BaseBuilder 实例(方法链)

返回类型:

BaseBuilder

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

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

Added in version 4.3.0.

参数:
  • $set (mixed) -- 行或行数组,行是数组或对象

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

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

返回:

BaseBuilder 实例(方法链)

返回类型:

BaseBuilder

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

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

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 语句并将其作为字符串返回。