在SQL语句中使用WHERE 1 = 1的目的是什么?

RaY*_*ell 17 sql where conditional-statements

可能的重复:
为什么sql查询具有"where 1 = 1"
为什么有人在SQL子句中使用WHERE 1 = 1 AND <conditions>?

我在不同的查询示例中看到了很多,它可能适用于所有SQL引擎.

如果存在没有定义条件的查询,则人们(特别是ORM框架)通常会添加始终为真的条件WHERE 1 = 1或类似的东西.

而不是

SELECT id, name FROM users;
Run Code Online (Sandbox Code Playgroud)

他们使用

SELECT id, name FROM users WHERE 1 = 1;
Run Code Online (Sandbox Code Playgroud)

我可以想到的唯一可能的原因是,如果你动态添加条件,你不必担心剥离初始条件,AND但是1 = 1如果查询中存在实际条件,则通常会剥离此条件.

CakePHP的实际示例(由框架生成):

(没有条件)

SELECT `User`.`id`, `User`.`login`
FROM `users` AS `User` WHERE 1 = 1 
ORDER BY `User`.`id` ASC;
Run Code Online (Sandbox Code Playgroud)

(有条件)

SELECT `User`.`id`, `User`.`login`
FROM `users` AS `User` 
WHERE `User`.`login` = 'me@example.com'
LIMIT 1;
Run Code Online (Sandbox Code Playgroud)

是否有任何理由增加额外的条件?

HeD*_*ges 19

当人们以编程方式构建sql查询时,这也是一种常见的做法,它更容易从'where 1 = 1'开始,然后附加'和customer.id =:custId',具体取决于是否提供了客户ID.因此,您始终可以追加以"和..."开头的查询的下一部分.

  • -1 这是重复的问题,它说“你不必担心剥离初始 AND ” (2认同)

pax*_*blo 11

人们使用它是因为在构建动态SQL查询时它们本质上是懒惰的.如果你从a开始,"where 1 = 1"那么你的所有额外条款就开始了"and",你不必弄明白.

并不是说天生懒惰有什么不妥.我已经看到了双链表,其中"空"列表由两个标记节点组成,您开始处理first->next直到last->prev包含.

这实际上删除了删除firstlast节点的所有特殊处理代码.在此设置中,每个节点都是一个中间节点,因为您无法删除firstlast.浪费了两个节点,但代码更简单,并且(更轻微)更快.

我见过的唯一一个"1 = 1"构造的地方是BIRT.报告通常使用位置参数,并使用Javascript进行修改以允许所有值.所以查询:

select * from tbl where col = ?
Run Code Online (Sandbox Code Playgroud)

当用户选择"*"用于的参数时,col修改为:

select * from tbl where ((col = ?) or (1 = 1))
Run Code Online (Sandbox Code Playgroud)

这允许使用新查询而无需摆弄位置参数细节.还有一个这样的参数.任何像样的DBMS(如DB2/Z)将优化该查询完全试图建构一个执行计划之前基本上去除该条款,所以没有权衡.


Chr*_*467 9

1 = 1是始终都RDBMS忽略.执行WHERE 1 = 1的查询没有权衡.

构建动态WHERE条件,如ORM框架或其他常常做的事情,更容易将真实状态附加到条件,因为您避免检查是否在当前条件前加上AND.

stmt += "WHERE 1=1";
if (v != null) {
   stmt += (" AND col = " + v.ToString());
}
Run Code Online (Sandbox Code Playgroud)

这是没有1 = 1时的样子.

var firstCondition = true;
...
if (v != null) {
   if (!firstCondition) {
      stmt += " AND ";
   }
   else {
       stmt += " WHERE ";
       firstCondition = false;
   }
   stmt += "col = " + v.ToString());
}
Run Code Online (Sandbox Code Playgroud)

  • 实际上,我倾向于这样做: cmd = "select ..."; sep = "哪里"; foreach (cond) { cmd += sep + cond; sep = " 和 "; } (2认同)

Noo*_*ilk 7

是的,通常是因为它从'where 1 = 0'开始,以强制语句失败.

这是一种更简单的方式将它包装在一个事务中,而不是最后提交它来测试你的查询.(这是首选方法).