为什么有人在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
答案 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
开头的查询并检查:
有些人会将第一个添加到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";
}
意味着不需要特殊代码:
WHERE 1 = 1
。由于我们已经有至少一个带有AND
的谓词,这意味着1 = 1
始终没问题。AND
。但同样,我们可能会变得懒惰,因为我们再次保证至少有一个谓词。这显然是一个坏主意,并建议使用已建立的数据访问框架或ORM以这种方式解析可选和条件谓词。
答案 12 :(得分:3)
如果您来到这里搜索WHERE 1
,请注意WHERE 1
和WHERE 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
补充说,这是一个明显的差异。一旦满足第一个条件就会返回表标题,或者其他一些疯狂,无论如何,它确实加快了速度。