Sql where 子句在过滤器为空的情况下返回所有内容

2023-12-13

我下面有一个 sql 表 -

SrNo  Name Value
1      A    X1
2      B    NULL
3      C    X3
4      D    X4
5      E    NULL
6      F    NULL 

我试图从表中获取所有记录,并满足以下两个条件 - a) 如果“@Value”列上的过滤器为 null,如下所示,则它应该返回包括 null 在内的所有记录

BEGIN
 Declare @Value varchar(50)
 SET @Value = NULL
 SELECT * from TestTable where Value = @Value
END

b)如果提供的@Value不为空,那么它应该返回该列(这肯定有效)

我尝试实现以下条件

BEGIN
     Declare @Value varchar(50)
     SET @Value = NULL
     SELECT * from TestTable where Value = IIF(@Value is NULL,Value,@Value)
    END

但上面也删除了空列。任何帮助或建议将不胜感激。


典型的方法是使用OR取决于是否提供了参数:

WHERE (Value = @Value OR @Value IS NULL);

但是,这可能会出现问题,因为您根据第一次调用获得了该查询的一个执行计划。这意味着如果第一次调用指定@Value = 1,这会导致索引查找,当参数为 NULL 时,第二个调用将获得索引查找(并且您不会喜欢它的性能)。类似地,在另一个方向上,第一个参数为 NULL,您将进行扫描,因为您要返回整个表,但是在第二次调用时,当您只需要一行(或很少)行时,您将仍然会进行扫描。

对此的典型反应是“添加OPTION (RECOMPILE);"!

这很棒,除非Value是唯一的,或者总是具有非常少量的任何给定值,并且您不断地使用导致小查找的显式值调用查询,您每次都无缘无故地重新编译该查询。每次需要扫描时,您每次都需要重新编译该查询,而无需这样做。

这种具有可选搜索参数的“厨房水槽”类型查询的折衷方案是使用动态 SQL(并且以不可注入的方式执行此操作很重要):

DECLARE @sql nvarchar(max) = N'SELECT ... FROM dbo.TestTable';

IF @Value IS NOT NULL
BEGIN
  SET @sql += N' WHERE Value = @Value';
END

SET @sql += N';';

EXEC sys.sp_executesql @sql, N'@Value varchar(50)', @Value;

现在您有两个不同的查询,它们将在两种不同的场景中以可预测的方式执行,并且不需要重新编译。如果您的数据可能存在偏差(某些值Value作为扫描或不同的计划形状效果会更好),然后您可以重新编译就在这种情况下:

  SET @sql += N' WHERE Value = @Value OPTION (RECOMPILE)';

如果您有知道会导致或不会导致问题的特殊值,或者如果您有多个参数,并且其中一些参数与唯一列相反,而其他参数则不然,您甚至可以执行此操作。

更多信息:

  • #BackToBasics:更新的厨房水槽示例
  • 保护自己免受 SQL 注入 - 第 1 部分
  • 保护自己免受 SQL 注入 - 第 2 部分
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Sql where 子句在过滤器为空的情况下返回所有内容 的相关文章

  • 从长到宽 - SQL [重复]

    这个问题在这里已经有答案了 我有一张很长的桌子 例如 Date Person Number 2015 01 03 A 4 2015 01 04 A 2 2015 01 05 A 3 2015 01 03 B 5 2015 01 04 B 6
  • “for”SQL Server 附近的语法不正确

    我想向其中已有数据的现有表添加一个新列 该列应该不为空 因此我想设置一个默认值 但是当我这样做时 它会抛出以下异常 for 附近的语法不正确 ALTER TABLE Semester ADD SIDNew uniqueidentifier
  • 如何将 nvarchar 解码为文本(SQL Server 2008 R2)?

    我有一个 SQL Server 2008 R2 表nvarchar 4000 field 存储该表的数据如下所示 696D616765206D61726B65643A5472 or 303131 011 我看到每个字符都编码为十六进制 我如
  • 如何使用 REST API 导出 SSRS 2017 报告

    我已经设置了 SSRS 2017 我需要使用他们的新 REST API 导出 SSRS 报告 我一直在查看 API 规范here https app swaggerhub com apis microsoft rs SSRS 2 0但我在
  • Crystal Reports 假定存储过程中列的数据类型错误

    Crystal Reports Engine 有时认为从某些存储过程返回的字段实际上是类型的原因是什么money is a varchar 255 因此 我无法应用任何数字格式 你确定你有铸成金钱的领域吗 您最近是否更改了数据类型 并且之后
  • 如何在SQL Server中创建SYS模式的表?

    可以在 SQL Server 2008 sys 架构中创建表吗 我知道可以将表标记为系统 但不能更改架构 有什么窍门吗 您无法将自己的对象添加到 sys 架构中 无法在 sys 架构中创建用户定义的对象 盖尔 埃里克森 MS SQL Ser
  • 使用具有外键的表将数据从 asp.net 页面插入到我的数据库中

    我是一名初学asp net程序员 我的项目是网上购物课程 我有一些问题 我有 4 个表 它们之间有一些外键 CREATE TABLE dbo orderdetails orderid INT NOT NULL classid INT NOT
  • T-SQL中有异或运算符吗?

    这是我的声明 IF UserName IS NULL AND EditorKey IS NULL OR UserName IS NOT NULL AND EditorKey IS NOT NULL BEGIN RAISERROR One o
  • 在 SQLCMD 模式下格式化输出?

    有没有办法可以指定输出文件格式SQLCMD模式这样我就可以使用它读回来BULK INSERT 我想做这样的事情 CONNECT SERVER1 OUT E test SELECT TOP 100 ID NAME FROM DB1 dbo T
  • 插入后用触发器更新多行(sql server)

    我有一个表 orderDetails 包含订单的产品 产品编号 color size quantity 和一个表库存 产品编号 size color stock 订单完成后 我使用此查询将项目插入表中orderDetails INSERT
  • 查询所有表数据并进行索引压缩

    是否有人碰巧拥有一个通用 SQL 语句 可以列出数据库中每个分区的所有表和索引及其当前的压缩设置 Thanks 编辑 这是我尝试查询表所得到的 但我不确定连接是否正确 我得到了重复项 这似乎是由于索引的存在引起的 SELECT t name
  • 表名搜索

    我使用以下命令在特定数据库的存储过程中搜索字符串 USE DBname SELECT Name FROM sys procedures WHERE OBJECT DEFINITION OBJECT ID LIKE xxx 修改上面的内容是否
  • 如何从经典 ASP 读取 SQL Always-加密列

    我维护一个经典的 ASP 应用程序 是的 我知道 我们正在开发它 并且需要访问 SQL 2017 中的 Always Encrypted 列 我已经导入了证书并在 SSMS 和 PowerShell 中进行了测试 这很有效 我在 ASP 中
  • Visual Studio 2010 与 SQL Server 2012 商业智能的正确安装顺序

    我有一个 Windows 7 64 位 旗舰版 虚拟机 想要安装以下内容 Visual Studio 2010 Ultimate SQL Server 2012 Business Intelligence with SSIS and SSR
  • 限制 SQL Server 连接到特定 IP 地址

    我想将 SQL Server 实例的连接限制为特定 IP 地址 我想阻止来自除特定列表之外的任何 IP 地址的任何连接 这是可以在 SQL Server 实例或数据库中配置的东西吗 听起来像是你会使用Windows防火墙 http tech
  • 连接两个表的查询的 SQL Server“FOR XML”输出

    我是 SQL Server 中 FOR XML 功能的新手 我正在使用 SQL Server 2012 我有两个表 Word 和 Word Expansion 样本数据 表 字 WordOID Word 1 PIPE 2 WIRE 表 Wo
  • SQL Server 用分隔符分割字符串

    我有一个输入字符串 100 2 3 101 2 1 103 2 3 我想解析它并将其添加到具有 3 列的表中 因此它应该是 f x col1 col2 col3 100 2 3 类似的其他数据以逗号分隔作为记录和 作为列 Thanks ni
  • 拆分列中的字符串并在列中添加值

    我有一个包含几行数据的表 如下所示 16 W 2 Work ALBO 00 Proposal ALxO Amendement 1 20091022 signed pdf 17 W 2 Work ALBO 00 Proposal Level1
  • SQL 删除表并重新创建并保留数据

    在我们最初的设计中 我们搞砸了表中的外键约束 现在表已充满数据 我们无法在不删除表中所有记录的情况下更改它 我能想到的唯一解决方案是创建一个备份表并将所有记录放在那里 然后删除所有记录 更改表并开始将它们添加回来 还有其他 更好 的想法吗
  • Spark.read 在 Databricks 中给出 KrbException

    我正在尝试从 databricks 笔记本连接到 SQL 数据库 以下是我的代码 jdbcDF spark read format com microsoft sqlserver jdbc spark option url jdbc sql

随机推荐