为什么有人在SQL子句中使用WHERE 1 = 1 AND <conditions>?</conditions>

时间:2008-10-28 10:37:05

标签: sql dynamic-sql

为什么有人在SQL子句中使用WHERE 1=1 AND <conditions>(通过连接字符串获得的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

21 个答案:

答案 0 :(得分:318)

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

and <condition>

并将它们连接在一起。在1=1开头,初始and有一些要关联的内容。

我从来没有见过这种用于任何注射防护的东西,正如你所说它看起来似乎不会有多大帮助。我已经看到它用作实现方便。 SQL查询引擎最终将忽略1=1,因此它不会对性能产生影响。

答案 1 :(得分:111)

只需在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

答案 2 :(得分:35)

我已经看到它在条件数量可变的情况下使用。

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

基本上,它可以节省您必须对条件进行测试,然后在它们之前添加“WHERE”字符串。

答案 3 :(得分:25)

似乎是一种懒惰的方式,总是知道你的WHERE子句已经定义,并且允许你不断检查是否是第一个条件而不断添加条件。

答案 4 :(得分:15)

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

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

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

答案 5 :(得分:14)

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

答案 6 :(得分:10)

实际上,我已经在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开头的查询并检查:

  • 这个名字叫Bob;和
  • 工资是&gt; $ 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

答案 7 :(得分:10)

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

答案 8 :(得分:7)

当我在数据库上测试或双重检查时,我发现这种模式非常有用,所以我可以非常快速地评论其他条件:

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

答案 9 :(得分:5)

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

implode (" AND ", $clauses);

因此避免了前导或尾随AND的问题。显然,只有当你知道你将至少有一个条款时,这才有用!

答案 10 :(得分:4)

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

MERGE INTO Circles
   USING 
      (
        SELECT pi
         FROM Constants
      ) AS SourceTable
   ON 1 = 1
WHEN MATCHED THEN 
  UPDATE
     SET circumference = 2 * SourceTable.pi * radius;

答案 11 :(得分:4)

  

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

我已经seen这样的homespun框架做了这样的事情( blush ),因为这允许将惰性解析实践应用于WHERE和{{ 1}} Sql关键字。

例如(我在这里以C#为例),考虑在Sql查询AND中对以下谓词进行条件解析:

string builder

&#34;福利&#34; var sqlQuery = "SELECT * FROM FOOS WHERE 1 = 1" if (shouldFilterForBars) { sqlQuery = sqlQuery + " AND Bars > 3"; } if (shouldFilterForBaz) { sqlQuery = sqlQuery + " AND Baz < 12"; } 意味着不需要特殊代码:

  • 对于 AND - 是否应该应用零,一个或两个谓词(Bars和Baz&#39; s),这将决定是否需要第一个WHERE 1 = 1。由于我们已经有至少一个带有AND的谓词,这意味着1 = 1始终没问题。
  • 根本没有谓词 - 在存在ZERO谓词的情况下,必须删除AND。但同样,我们可能会变得懒惰,因为我们再次保证至少有一个谓词。

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

答案 12 :(得分:3)

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

答案 13 :(得分:1)

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

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

答案 14 :(得分:1)

这在您必须使用动态查询的情况下非常有用 你必须附加一些过滤器选项。就像你包含选项0的状态是非活动的,1是活动的。根据选项,只有两个可用选项(0和1),但如果要显示所有记录,则包含在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);

答案 15 :(得分:1)

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

SELECT
*
FROM MyTable

WHERE 1=1

然后我检查了其他数字

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

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

答案 16 :(得分: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的虚拟条件都可以作为填充条件。

答案 17 :(得分:0)

在生产代码中看到这一点,并向前辈寻求帮助。

他们的回答:

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

and <condition>

然后继续。

答案 18 :(得分:0)

我通常在为具有许多用户可以选择的下拉值的报表构建动态SQL时执行此操作。由于用户可能会或可能不会从每个下拉列表中选择值,因此我们最终难以确定哪个条件是第一个where子句。因此,我们最后使用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'.

答案 19 :(得分:0)

使用类似1=1的谓词是一种常规提示,有时用于强制访问计划使用或不使用索引扫描。之所以使用它,是因为在where子句中使用多嵌套连接查询时有很多谓词,有时甚至使用所有索引都会导致访问计划读取每个表 - 全表扫描。这只是DBA用来欺骗dbms使用更高效路径的许多提示中的一个。只是不要扔一个;你需要一个dba来分析查询,因为它并不总是有效。

答案 20 :(得分:-1)

我第一次看到ADO和经典的asp,我得到的答案是:性能。 如果你直接

Select * from tablename

并将其作为sql命令/文本传递,您将通过

获得显着的性能提升

Where 1=1

补充说,这是一个明显的差异。一旦满足第一个条件就会返回表标题,或者其他一些疯狂,无论如何,它确实加快了速度。