为什么有人会WHERE 1=1 AND
在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
Greg Hewgill.. 336
如果条件列表在编译时未知,而是在运行时构建,则不必担心是否有一个或多个条件.你可以生成所有这些:
and
并将它们连接在一起.随着1=1
在开始时,最初and
有一些与之交往.
我从来没有见过这种用于任何注射保护的东西,正如你所说它看起来似乎不会有多大帮助.我已经看到它用作实现方便.SQL查询引擎最终会忽略1=1
它,因此它应该没有性能影响.
如果条件列表在编译时未知,而是在运行时构建,则不必担心是否有一个或多个条件.你可以生成所有这些:
and
并将它们连接在一起.随着1=1
在开始时,最初and
有一些与之交往.
我从来没有见过这种用于任何注射保护的东西,正如你所说它看起来似乎不会有多大帮助.我已经看到它用作实现方便.SQL查询引擎最终会忽略1=1
它,因此它应该没有性能影响.
只需在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
我已经看到它在条件数量可变的情况下使用.
您可以使用"AND"字符串连接条件.然后,不是计算您传入的条件数,而是在库存SQL语句的末尾放置一个"WHERE 1 = 1"并抛出连接条件.
基本上,它可以节省您必须对条件进行测试,然后在它们之前添加"WHERE"字符串.
看起来像一种懒惰的方式,总是知道你的WHERE子句已经定义,并允许你继续添加条件,而不必检查它是否是第一个.
间接相关:当使用1 = 2时:
CREATE TABLE New_table_name as select * FROM Old_table_name WHERE 1 = 2;
这将创建一个与旧表具有相同模式的新表.(如果你想加载一些数据进行比较,非常方便)
1 = 1表达式通常用于生成的sql代码中.此表达式可以简化sql生成代码,减少条件语句的数量.
实际上,我已经在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
其中1 = 0,这样做是为了检查表是否存在.不知道为什么使用1 = 1.
当我在数据库上测试或重复检查时,我发现这个模式很有用,所以我可以非常快速地评论其他条件:
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
虽然我可以看到1 = 1对生成的SQL很有用,但我在PHP中使用的一种技术是创建一个子句数组然后再做
implode (" AND ", $clauses);
从而避免了领先或尾随AND的问题.显然,只有当你知道你将至少有一个条款时,这才有用!
这是一个密切相关的示例:使用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;
为什么有人使用WHERE 1 = 1 AND
我已经看到过本地化框架所做的事情(blush),因为这允许将懒惰的解析实践同时应用于WHERE
和AND
Sql关键字。
例如(我在这里以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以这种方式解析可选谓词和条件谓词。