Sql server 如何在存储过程中动态添加到TSQL Where子句

Sql server 如何在存储过程中动态添加到TSQL Where子句,sql-server,tsql,Sql Server,Tsql,如何向TSQL Where子句动态添加条件 我试图避免在两个完整的Select语句之间进行选择。下面的代码与我的实际代码非常相似,但不太复杂 SELECT COUNT(*) FROM MyTable WHERE ShipDate >= @FirstDayOfMonth AND ShipDate < @LastDayOfMonth AND OrderType = 1 AND NOT OrderCode LIKE '%3' AND NOT OrderCod

如何向TSQL Where子句动态添加条件 我试图避免在两个完整的Select语句之间进行选择。下面的代码与我的实际代码非常相似,但不太复杂

SELECT COUNT(*)
FROM   MyTable
WHERE  ShipDate >= @FirstDayOfMonth
AND    ShipDate <  @LastDayOfMonth
AND    OrderType = 1
AND    NOT OrderCode LIKE '%3'
AND    NOT OrderCode LIKE '%4';
选择计数(*)
从MyTable
其中ShipDate>=@FirstDayOfMonth
装运日期<@每月最后一天
和OrderType=1
而不是像“%3”这样的订单代码
而不是像“%4”这样的订单代码;

我希望能够根据存储过程参数的值添加或删除最后两个条件。即:如果@ExcludePhoneOrders=False,请不要使用最后两个Where子句条件。

您可以将查询转储到varchar,然后使用if语句选择性地附加额外的Where子句信息,然后将整个过程传递给sp_executesql。

我不确定您是否打算包含或排除,但这里有一个尝试

SELECT COUNT(*)
FROM   MyTable
WHERE  ShipDate >= @FirstDayOfMonth
AND    ShipDate <  @LastDayOfMonth
AND    OrderType = 1
AND    (@ExcludePhoneOrders = False OR (NOT OrderCode LIKE '%3' AND NOT OrderCode LIKE '%4'));
选择计数(*)
从MyTable
其中ShipDate>=@FirstDayOfMonth
装运日期<@每月最后一天
和OrderType=1
和(@ExcludePhoneOrders=False或(不是像“%3”这样的OrderCode,也不是像“%4”)那样的OrderCode);
选择计数(*)
从MyTable
其中ShipDate>=@FirstDayOfMonth
装运日期<@每月最后一天
和OrderType=1
及(
(@ExcludePhoneOrders为False,不是像“%3”这样的OrderCode,也不是像“%4”这样的OrderCode)
或
@ExcludePhoneOrders=False
)

如果参数为null

,则需要考虑句柄空值。 如果我使用的数据类型不正确,您应该更改它们。 但主要概念应该保持不变。 让我知道进展如何

Create proc GetOrders
   ....,
   @FirstDayOfMonth int,
   @LastDayOfMonth int,
   ....
AS
DECLARE @SQL varchar(1000)
DECLARE @PARAMS nvarchar(100);

set @SQL='SELECT COUNT(*) FROM   MyTable WHERE  ShipDate >= @FirstDay_OfMonth AND    ShipDate <  @LastDay_OfMonth AND    OrderType = 1';

if(@ExcludePhoneOrders = 1)
begin
  set @SQL=@SQL + ' AND NOT OrderCode LIKE ''%3'' AND NOT OrderCode LIKE ''%4'''
end

SET @PARAMS = '@FirstDayOfMonth int, @LastDayOfMonth int'
EXECUTE sp_executesql @SQL, @PARAMS, @FirstDay_OfMonth = @FirstDayOfMonth, @LastDay_OfMonth=@LastDayOfMonth
GO
Create proc GetOrders
....,
@月初一日整数,
@每月最后一天整数,
....
作为
声明@SQL varchar(1000)
声明@PARAMS nvarchar(100);
从MyTable中设置@SQL='SELECT COUNT(*),其中ShipDate>=@FirstDay\u of month,ShipDate<@LastDay\u of month,OrderType=1';
如果(@ExcludePhoneOrders=1)
开始
设置@SQL=@SQL+,而不是像“%3”这样的医嘱代码,也不是像“%4”这样的医嘱代码
结束
设置@PARAMS='@FirstDayOfMonth int,@LastDayOfMonth int'
执行sp_executesql@SQL、@PARAMS、@FirstDay_of month=@FirstDayOfMonth、@LastDay_of month=@LastDayOfMonth
去

谢谢,更改为
@ExcludePhoneOrders=False或…
效果很好。您知道它为什么工作吗?左侧或右侧的逻辑必须为true才能显示行。如果@ExcludePhoneOrders=False,那么它甚至不需要解析条件的右侧。这也起到了作用。我使用了Korey的代码,因为它少了一行。谢谢你的帮助。我现在必须试着理解SQL是如何处理这段代码的;比如它为什么起作用。我用默认参数处理NULL。如果没有其他方法,那将是我最后的选择。谢谢,谢谢你的努力,Projapati。这是一个很好的解决方案。我试图让代码尽可能可读,所以我接受了Korey的建议。您的代码是一个很好的替代方案。解决方案:
其中ShipDate>=@FirstDayOfMonth
和ShipDate
和OrderType=1
和(@ExcludePhoneOrders=False
或((不是像'%3')
这样的OrderCode和(不是像'%4'))
Create proc GetOrders
   ....,
   @FirstDayOfMonth int,
   @LastDayOfMonth int,
   ....
AS
DECLARE @SQL varchar(1000)
DECLARE @PARAMS nvarchar(100);

set @SQL='SELECT COUNT(*) FROM   MyTable WHERE  ShipDate >= @FirstDay_OfMonth AND    ShipDate <  @LastDay_OfMonth AND    OrderType = 1';

if(@ExcludePhoneOrders = 1)
begin
  set @SQL=@SQL + ' AND NOT OrderCode LIKE ''%3'' AND NOT OrderCode LIKE ''%4'''
end

SET @PARAMS = '@FirstDayOfMonth int, @LastDayOfMonth int'
EXECUTE sp_executesql @SQL, @PARAMS, @FirstDay_OfMonth = @FirstDayOfMonth, @LastDay_OfMonth=@LastDayOfMonth
GO