292

为什么有人会WHERE 1=1 AND <conditions>在 SQL 子句中使用(无论是通过连接字符串获得的 SQL,还是视图定义)

我在某处看到这将用于防止 SQL 注入,但这似乎很奇怪。

如果有注入WHERE 1 = 1 AND injected OR 1=1将有相同的结果injected OR 1=1

稍后编辑:视图定义中的用法如何?


谢谢您的回答。

不过,我不明白为什么有人会使用这种结构来定义视图,或者在存储过程中使用它。

以此为例:

CREATE VIEW vTest AS
SELECT FROM Table WHERE 1=1 AND table.Field=Value
4

21 回答 21

381

如果条件列表在编译时未知,而是在运行时构建,则您不必担心是否有一个或多个条件。你可以像这样生成它们:

and <condition>

并将它们连接在一起。在1=1开头,首字母and有一些关联。

我从未见过它用于任何类型的注射保护,正如你所说,它似乎没有多大帮助。我已经看到它被用作实现便利。SQL 查询引擎最终会忽略它,1=1因此它应该不会影响性能。

于 2008-10-28T10:39:59.423 回答
123

只需在 Greg 的答案中添加示例代码:

dim sqlstmt as new StringBuilder
sqlstmt.add("SELECT * FROM Products")
sqlstmt.add(" WHERE 1=1") 

''// From now on you don't have to worry if you must 
''// append AND or WHERE because you know the WHERE is there
If ProductCategoryID <> 0 then
  sqlstmt.AppendFormat(" AND ProductCategoryID = {0}", trim(ProductCategoryID))
end if
If MinimunPrice > 0 then
  sqlstmt.AppendFormat(" AND Price >= {0}", trim(MinimunPrice))
end if
于 2008-10-28T10:53:21.270 回答
39

我已经看到当条件的数量可以变化时使用它。

您可以使用“AND”字符串连接条件。然后,不是计算您传入的条件的数量,而是在您的股票 SQL 语句的末尾放置一个“WHERE 1=1”并抛出连接的条件。

基本上,它使您不必对条件进行测试,然后在它们之前添加一个“WHERE”字符串。

于 2008-10-28T10:43:05.503 回答
28

总是知道您的 WHERE 子句已定义并允许您继续添加条件而无需检查它是否是第一个条件,这似乎是一种懒惰的方式。

于 2008-10-28T10:40:05.493 回答
22

间接相关:当使用 1=2 时:

CREATE TABLE New_table_name 
as 
select * 
FROM Old_table_name 
WHERE 1 = 2;

这将创建一个与旧表具有相同架构的新表。(如果您想加载一些数据进行比较,非常方便)

于 2013-02-20T14:37:24.097 回答
17

1 = 1 表达式常用于生成的 sql 代码中。该表达式可以简化 sql 生成代码,减少条件语句的数量。

于 2008-10-28T10:40:46.833 回答
15

当我在数据库上测试或仔细检查事物时,我发现这种模式很有用,因此我可以非常快速地评论其他条件:

CREATE VIEW vTest AS
SELECT FROM Table WHERE 1=1 
AND Table.Field=Value
AND Table.IsValid=true

变成:

CREATE VIEW vTest AS
SELECT FROM Table WHERE 1=1 
--AND Table.Field=Value
--AND Table.IsValid=true
于 2016-05-18T21:57:00.807 回答
12

实际上,我已经在 BIRT 报告中看到过这种东西。传递给 BIRT 运行时的查询格式如下:

select a,b,c from t where a = ?

和“?” 在运行时被从下拉框中选择的实际参数值替换。下拉列表中的选项由以下方式给出:

select distinct a from t
union all
select '*' from sysibm.sysdummy1

这样您就可以获得所有可能的值加上“ *”。如果用户*从下拉框中选择“”(意味着应选择 a 的所有值),则必须在运行之前(通过 Javascript)修改查询。

自从“?” 是一个位置参数,必须保留在那里才能让其他事情正常工作,Javascript 将查询修改为:

select a,b,c from t where ((a = ?) or (1==1))

这基本上消除了 where 子句的影响,同时仍然保留了位置参数。

我还看到了惰性编码器在动态创建 SQL 查询时使用的 AND 案例。

select * from t假设您必须动态创建一个以检查开头的查询:

  • 名字是鲍勃;和
  • 薪水> 20,000美元

有些人会用 WHERE 添加第一个,然后用 AND 添加后续的:

select * from t where name = 'Bob' and salary > 20000

懒惰的程序员(这不一定是一个特性)不会区分添加的条件,他们会从select * from t where 1=1添加 AND 子句开始,然后添加子句。

select * from t where 1=1 and name = 'Bob' and salary > 20000
于 2008-10-28T12:13:03.183 回答
10

其中 1=0,这样做是为了检查表是否存在。不知道为什么使用 1=1。

于 2009-09-14T05:38:29.543 回答
6

虽然我可以看到 1=1 对于生成的 SQL 很有用,但我在 PHP 中使用的一种技术是创建一个子句数组,然后执行

implode (" AND ", $clauses);

从而避免出现前导或尾随 AND 的问题。显然,这仅在您知道您将拥有至少一个子句时才有用!

于 2010-01-07T16:00:12.790 回答
6

这是一个密切相关的示例:使用 SQLMERGE语句使用源表中的所有值更新目标表,其中没有要加入的公共属性,例如

MERGE INTO Circles
   USING 
      (
        SELECT pi
         FROM Constants
      ) AS SourceTable
   ON 1 = 1
WHEN MATCHED THEN 
  UPDATE
     SET circumference = 2 * SourceTable.pi * radius;
于 2011-11-17T09:33:42.587 回答
5

为什么有人会使用 WHERE 1=1 AND<proper conditions>

见过朴素的框架做这样的事情(blush),因为这允许将惰性解析实践应用于 theWHEREANDSql 关键字。

例如(我在这里使用 C# 作为示例),考虑在 Sql 查询中对以下谓词进行条件解析string builder

var sqlQuery = "SELECT * FROM FOOS WHERE 1 = 1"
if (shouldFilterForBars)
{
    sqlQuery = sqlQuery + " AND Bars > 3";
}
if (shouldFilterForBaz)
{
    sqlQuery = sqlQuery + " AND Baz < 12";
}

的“好处”WHERE 1 = 1意味着不需要特殊代码:

  • 对于AND - 是否应应用零、一个或两个谓词(Bars 和 Baz's),这将确定是否AND需要第一个。由于我们已经至少有一个带有 的谓词1 = 1,这意味着AND总是可以的。
  • 对于根本没有谓词 - 如果谓词为零,则WHERE必须删除。但同样,我们可以偷懒,因为我们再次保证了至少一个谓词。

这显然是个坏主意,建议使用已建立的数据访问框架或ORM以这种方式解析可选和条件谓词。

于 2014-12-23T14:53:02.013 回答
5

如果您来这里搜索WHERE 1,请注意WHERE 1WHERE 1=1是相同的。WHERE 1很少使用,因为某些数据库系统考虑到它WHERE 1不是真正的布尔值而拒绝它。

于 2016-04-05T13:06:56.470 回答
3

查看所有答案后,我决定进行一些实验,例如

SELECT
*
FROM MyTable

WHERE 1=1

然后我检查了其他号码

WHERE 2=2
WHERE 10=10
WHERE 99=99

ect 完成所有检查后,查询运行城镇是相同的。即使没有 where 子句。我不喜欢语法

于 2018-03-16T15:05:16.383 回答
2

这在您必须使用动态查询的情况下很有用,其中在 where 子句中您必须附加一些过滤器选项。就像如果您包含选项 0 状态为非活动状态,1 为活动状态。根据选项,只有两个可用选项(0 和 1),但如果要显示所有记录,可以方便地包含在 where close 1=1 中。请参见下面的示例:

Declare @SearchValue    varchar(8) 
Declare @SQLQuery varchar(max) = '
Select [FirstName]
    ,[LastName]
    ,[MiddleName]
    ,[BirthDate]
,Case
    when [Status] = 0 then ''Inactive''
    when [Status] = 1 then ''Active''
end as [Status]'

Declare @SearchOption nvarchar(100)
If (@SearchValue = 'Active')
Begin
    Set @SearchOption = ' Where a.[Status] = 1'
End

If (@SearchValue = 'Inactive')
Begin
    Set @SearchOption = ' Where a.[Status] = 0'
End

If (@SearchValue = 'All')
Begin
    Set @SearchOption = ' Where 1=1'
End

Set @SQLQuery = @SQLQuery + @SearchOption

Exec(@SQLQuery);
于 2018-02-16T07:22:40.707 回答
1

我通常在为具有许多用户可以选择的下拉值的报表构建动态 SQL 时这样做。由于用户可能会或可能不会从每个下拉列表中选择值,因此我们最终很难确定哪个条件是第一个 where 子句。所以我们最后用 a 填充查询,where 1=1然后添加所有 where 子句。

就像是

select column1, column2 from my table where 1=1 {name} {age};

然后我们将像这样构建 where 子句并将其作为参数值传递

string name_whereClause= ddlName.SelectedIndex > 0 ? "AND name ='"+ ddlName.SelectedValue+ "'" : "";

由于我们在运行时不知道 where 子句的选择,所以这有助于我们确定是否包含'AND' or 'WHERE'.

于 2014-03-19T05:43:36.750 回答
1

使“where 1=1”成为所有查询的标准还可以通过将其替换为 where 1 = 0 来轻松验证 sql,这在您有成批的命令/文件时很方便。

还可以很容易地找到任何查询的 from/join 部分的结尾。如果缩进正确,即使是带有子查询的查询。

于 2020-12-19T14:25:08.937 回答
0

我第一次遇到这个是用 ADO 和经典的 asp,我得到的答案是:性能。 如果你做一个直线

Select * from tablename

并将其作为 sql 命令/文本传递,您将获得显着的性能提升

Where 1=1

补充说,这是一个明显的差异。与第一个条件满足后立即返回表头有关,或者其他一些疯狂的事情,无论如何,它确实加快了速度。

于 2009-02-05T18:44:14.893 回答
0

使用谓词 like1=1是一种正常的提示,有时用于强制访问计划使用或不使用索引扫描。使用它的原因是当您在 where 子句中使用具有许多谓词的多嵌套联接查询时,有时即使使用所有索引也会导致访问计划读取每个表 - 全表扫描。这只是 DBA 用来欺骗 dbms 使用更有效路径的众多提示之一。只是不要扔进去;您需要一个 dba 来分析查询,因为它并不总是有效。

于 2012-08-10T15:50:14.400 回答
0

这是一个用例......但是我不太关心为什么我应该使用或不使用 1 = 1 的技术细节。我正在编写一个函数,使用 pyodbc 从 SQL Server 检索一些数据。我正在寻找一种where在我的代码中的关键字之后强制填充的方法。这确实是一个很好的建议:

if _where == '': _where = '1=1'
...
...
...
cur.execute(f'select {predicate} from {table_name} where {_where}')

原因是我无法在 _where 子句变量中同时实现关键字“where”。所以,我认为使用任何评估为 true 的虚拟条件都可以作为填充物。

于 2020-06-12T02:31:31.113 回答
0

在生产代码中看到这个,请前辈帮忙。

他们的回答:

- 我们使用 1=1 所以当我们必须添加一个新条件时,我们可以输入

and <condition>

继续做下去。

于 2021-04-16T17:41:41.307 回答