为啥0and1=0

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了为啥0and1=0相关的知识,希望对你有一定的参考价值。

参考技术A and是位运算,(n and 1)就是n的2进制下个位与1取and,and的运算是:1 and 1=1,1 and 0=0,0 and 1=0,0 and 0=0 ;

为啥有人会在 SQL 子句中使用 WHERE 1=1 AND <conditions> ?

【中文标题】为啥有人会在 SQL 子句中使用 WHERE 1=1 AND <conditions> ?【英文标题】:Why would someone use WHERE 1=1 AND <conditions> in a SQL clause?为什么有人会在 SQL 子句中使用 WHERE 1=1 AND <conditions> ? 【发布时间】:2010-09-19 13:26:40 【问题描述】:

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

【问题讨论】:

“为什么有人会使用这种结构来定义视图” 可能是出于习惯。它在静态查询中没有任何功能优势。 Nobody should use Dynamic SQL 【参考方案1】:

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

and <condition>

并将它们连接在一起。以 1=1 开头,最初的 and 有一些关联。

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

【讨论】:

有时候不是懒惰,而是代码更简洁。 处理尾随 AND 或 COMMA 并不肮脏……没有什么比 SQL 中的 1=1 更干净了。 DBA?它们是干什么用的? :) DBA 会在程序员认为他们知道如何有效地使用数据库之后进行清理。 "Lazy" 我喜欢认为它很聪明,而不是懒惰。您正在避免重复代码和不必要的条件检查。如果无法添加 where 1=1 (Oracle) 或 where true (Postgres),我将不得不检查每个条件是否是第一个条件。这样做没有意义,只会增加更多样板代码。【参考方案2】:

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

【讨论】:

"Lazy" 我喜欢认为它很聪明,而不是懒惰。您正在避免重复代码和不必要的条件检查。如果无法添加 where 1=1 (Oracle) 或 where true (Postgres),我将不得不检查每个条件是否是第一个条件。这样做没有意义,只会增加更多样板代码。 @ADTC 编写代码通常(如果不是大部分)是关于处理不同的条件。这只是需要处理的另一个条件,我个人认为这是懒惰的,它会污染生成的 SQL。如果您将代码设计为在一个位置添加“Where 1 = 1”,您可以 - 无需额外努力 - 处理代码中该位置的零条件和多个条件之间的差异。不过,我的猜测是,“Where 1 = 1”的倡导者将它洒在他们的代码库中,这让我得出了懒惰滋生懒惰的结论。 @JasonS Laziness 是发明之父。 @ADTC 我很懒,因为我不喜欢更新几百个地方的代码,所以发明了一个地方。对我来说WHERE 1=1 产生了在多个位置维护相同代码并在所有生成的 SQL 中读取它的额外工作。我比你想象的还要懒!【参考方案3】:

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

【讨论】:

【参考方案4】:

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

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

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

【讨论】:

【参考方案5】:

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

【讨论】:

有点老套,但似乎是一个有效的用途。 这应该是公认的答案。这种做法实际上只是为了不必确定您有多少条件。【参考方案6】:

实际上,我在 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

【讨论】:

"Lazy" 我喜欢认为它很聪明,而不是懒惰。您正在避免重复代码和不必要的条件检查。如果无法添加 where 1=1 (Oracle) 或 where true (Postgres),我将不得不检查每个条件是否是第一个条件。这样做没有任何意义,只会添加更多样板代码。 @ADTC,我并不是说懒惰。事实上,懒惰是编程中的一个特性 :-) 我会澄清一下。 懒惰是万恶之源【参考方案7】:

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

Select * from tablename

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

Where 1=1

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

【讨论】:

如果是这样,为什么 DBMS 不总是添加它? 我也见过这个,但是很抱歉我不能指定引擎/版本。这是我 20 多年 sql 编码中的某个时刻。我认为发生的事情是没有任何 Where 子句,执行计划最终进行了表扫描;添加 where 1 =1 会产生更好的计划。但 anedote data 的复数;我不能发誓根本问题不是临时网络或其他资源问题:-p【参考方案8】:

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

【讨论】:

看到这用于从数据库中返回一个空结果集,用作新记录的持有者。【参考方案9】:

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

implode (" AND ", $clauses);

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

【讨论】:

这就是 1=1 的用武之地。它为您提供了“至少一个子句”,因此您不必担心只是拍打“ AND abc” 我喜欢这个主意!有关更完整的示例,请参见此处***.com/questions/35326160/…【参考方案10】:

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

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

【讨论】:

您是否有任何引用记录了某些数据库的这种行为?【参考方案12】:

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

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

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

【讨论】:

忘了添加,虽然它会创建一个与旧表具有相同数据的新表,但新表不会有其他约束,如旧表中的外键【参考方案13】:

当我为具有许多用户可以选择的下拉值的报表构建动态 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'.

【讨论】:

【参考方案14】:

为什么有人会使用 WHERE 1=1 AND &lt;proper conditions&gt;

我有 seen homepun 框架做这样的事情 (blush),因为这允许将惰性解析实践应用于 WHEREAND 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 以这种方式解析可选和条件谓词。

【讨论】:

或者如果你自己滚动,where 子句构建器应该在你的代码中的一个地方。然后,您可以在代码中的单个位置处理零个谓词或多个谓词。我怀疑WHERE 1=1 的存在是一个公平的指标,表明情况并非如此,代码库中到处都是WHERE 1=1 的字符串位,这对我来说表明存在应用程序架构问题,我猜不是唯一的一个! 其实这个想法并没有什么“坏”,更不用说“明显”的错误了。在所有情况下,ORM 也不是正确的方法。学习 SQL 和关系代数的人...【参考方案15】:

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

【讨论】:

【参考方案16】:

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

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

【讨论】:

【参考方案17】:

这在您必须使用动态查询的情况下很有用 子句您必须附加一些过滤器选项。就像如果您包含选项 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);

【讨论】:

【参考方案18】:

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

SELECT
*
FROM MyTable

WHERE 1=1

然后我检查了其他号码

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

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

【讨论】:

【参考方案19】:

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

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

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

【讨论】:

【参考方案20】:

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

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

【讨论】:

【参考方案21】:

在生产代码中看到这个,向前辈求助。

他们的回答:

-我们使用 1=1,所以当我们必须添加新条件时,我们只需键入

and <condition>

然后继续。

【讨论】:

以上是关于为啥0and1=0的主要内容,如果未能解决你的问题,请参考以下文章

为啥我的 MLP 神经网络的输出在 0 和 1 之间?

我有一个包含 0 和 1 值的数组。如果我将它与 -1 相乘,则会产生空数组。为啥?

为啥 main 的默认返回值为 0 而不是 EXIT_SUCCESS?

shell脚本编程学习笔记-逻辑操作符

525. Contiguous Array

[leetcode-525-Contiguous Array]