为什么有人会使用WHERE 1=1和<;条件>;在SQL子句中?

为什么有人会使用WHERE 1=1和<;条件>;在SQL子句中?,sql,dynamic-sql,Sql,Dynamic Sql,为什么有人会在SQL子句中使用WHERE 1=1和(或者是通过连接字符串获得的SQL,或者是视图定义) 我曾在某个地方看到,这将用于防止SQL注入,但它似乎非常奇怪 如果存在注入,其中1=1和注入或1=1将产生与注入或1=1相同的结果 后期编辑:视图定义中的用法如何 谢谢你的回答 尽管如此, 我不明白为什么会有人使用这种结构来定义视图,或者在存储过程中使用它 以此为例: CREATE VIEW vTest AS SELECT FROM Table WHERE 1=1 AND table.Fie

为什么有人会在SQL子句中使用
WHERE 1=1和
(或者是通过连接字符串获得的SQL,或者是视图定义)

我曾在某个地方看到,这将用于防止SQL注入,但它似乎非常奇怪

如果存在注入
,其中1=1和注入或1=1
将产生与
注入或1=1
相同的结果

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


谢谢你的回答

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

以此为例:

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

如果编译时不知道条件列表,而是在运行时生成的,则不必担心是否有一个或多个条件。您可以按如下方式生成它们:

and <condition>
并将它们连接在一起。开始时的
1=1
,初始的
有一些关联


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

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

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

我见过在条件数量可变时使用它

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


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

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

dim sqlstmt作为新的StringBuilder
sqlstmt.add(“从产品中选择*)
sqlstmt.add(“其中1=1”)
''//从现在起,如果必须,你不必担心
''//追加和/或在哪里,因为您知道在哪里
如果ProductCategoryID为0,则
AppendFormat(“AND ProductCategoryID={0}”,trim(ProductCategoryID))
如果结束
如果最小价格>0,则
AppendFormat(“和价格>={0}”,修剪(最小价格))
如果结束

事实上,我在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*fromt
开头的查询,并检查:

  • 名字叫鲍勃;及
  • 薪水超过20000美元
有些人会将第一个加上WHERE,然后再加上一个,因此:

select * from t where name = 'Bob' and salary > 20000
懒惰的程序员(这不一定是一个坏特性)不会区分添加的条件,他们会从t开始,其中1=1,然后添加and子句

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

我第一次遇到这个问题时使用了ADO和classic asp,得到的答案是:性能。 如果你直奔终点

从tablename中选择*

并将其作为sql命令/文本传入,您将在

其中1=1


此外,这是一个明显的区别。与满足第一个条件后立即返回表头有关,或者与其他疯狂行为有关,总之,它确实加快了速度。

如果1=0,则执行此操作是为了检查表是否存在。不知道为什么使用1=1。

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

implode (" AND ", $clauses);

从而避免了具有前导或尾随和的问题。显然,只有当您知道您至少要有一个子句时,这才有用

这里有一个密切相关的示例:使用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;

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

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

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

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

我通常在为一个报表构建动态SQL时这样做,该报表具有许多用户可以选择的下拉值。由于用户可能会也可能不会从每个下拉列表中选择值,我们最终很难确定是哪一个条件
select column1, column2 from my table where 1=1 {name} {age};
string name_whereClause= ddlName.SelectedIndex > 0 ? "AND name ='"+ ddlName.SelectedValue+ "'" : "";
var sqlQuery = "SELECT * FROM FOOS WHERE 1 = 1"
if (shouldFilterForBars)
{
    sqlQuery = sqlQuery + " AND Bars > 3";
}
if (shouldFilterForBaz)
{
    sqlQuery = sqlQuery + " AND Baz < 12";
}
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
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);
SELECT
*
FROM MyTable

WHERE 1=1
WHERE 2=2
WHERE 10=10
WHERE 99=99
if _where == '': _where = '1=1'
...
...
...
cur.execute(f'select {predicate} from {table_name} where {_where}')
and <condition>