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

我在某个地方看到过,这将用于防止SQL注入,但这看起来非常奇怪。

如果有一个注入WHERE 1=1和注入OR 1=1将有相同的结果注入OR 1=1。

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


谢谢你的回答。

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

举个例子:

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

当前回答

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

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

原因是我不能在_where子句变量中一起实现关键字“where”。因此,我认为使用任何计算结果为真的虚拟条件都可以作为填充符。

其他回答

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

我的名字叫鲍勃;而且 薪水是2万美元

有些人会在第一个单词后面加上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

我曾见过在条件数量可变的情况下使用这种方法。

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

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

我通常在为一个有许多用户可以选择的下拉值的报告构建动态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”或“where”方面帮助我们很大。

使“where 1=1”成为所有查询的标准,还可以通过将其替换为where 1= 0来简单地验证sql,当您有批量命令/文件时非常方便。

这也使得查找任何查询的from/join部分的结尾变得非常容易。甚至带有子查询的查询,如果缩进得当。

回顾了所有的答案,我决定做一些实验

SELECT
*
FROM MyTable

WHERE 1=1

然后我用其他号码核对了一下

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

等 在完成所有检查之后,查询run town是相同的。即使没有where从句。我不喜欢这种语法