Sql server SQL-Where子句中的Case以减少IF语句
尝试执行时出错。我不是DBA,但我需要根据传入的变量在where子句中进行筛选。我使用了一个包含IF语句的大型语句,但看起来很糟糕,所以我想出了这个主意,但却出现了错误 查询:Sql server SQL-Where子句中的Case以减少IF语句,sql-server,tsql,Sql Server,Tsql,尝试执行时出错。我不是DBA,但我需要根据传入的变量在where子句中进行筛选。我使用了一个包含IF语句的大型语句,但看起来很糟糕,所以我想出了这个主意,但却出现了错误 查询: DECLARE @VariableName AS NVARCHAR(100), @VariableValue AS NVARCHAR(MAX), @PileFrom AS INT, @PileTo AS INT, @BeginDate AS DATETIME, @E
DECLARE
@VariableName AS NVARCHAR(100),
@VariableValue AS NVARCHAR(MAX),
@PileFrom AS INT,
@PileTo AS INT,
@BeginDate AS DATETIME,
@EndDate AS DATETIME,
@Truck AS BIT,
@Train AS BIT
--AS
BEGIN
IF @BeginDate = '' BEGIN
SET @Begindate = '1/1/1900'
END
IF @EndDate = '' BEGIN
SET @EndDate = '1/1/9999'
END
IF @Truck = 1 BEGIN
SELECT
Car_ID,
PO_Number,
Vendor,
Shipper,
Commodity,
Date_Weighed_In,
Date_Weighed_Out,
Pile_No AS 'PILe From',
Pile_No1 AS 'Pile To',
Operator_In,
Operator_Out,
Comments_In,
Comments_Out,
Weight_In,
Weight_Out,
Transaction_Num,
Record_time_Stamp
FROM
dbo.Transactions_Truck
WHERE
(Date_Weighed_IN BETWEEN @BeginDate AND @EndDate) AND
CASE
WHEN @VariableName = 'rbCardID' THEN Car_ID = @VariableValue
WHEN @VariableName = 'rbPONumber' THEN PO_Number = @VariableValue
WHEN @VariableName = 'rbVendor' THEN Vendor = @VariableValue
WHEN @VariableName = 'rbCommodity' THEN Commodity = @VariableValue
WHEN @VariableName = 'rbPileNumber' THEN Pile_No = @PileFrom AND Pile_No1 = @PileTo
WHEN @VariableName = 'rbTransactionNum' THEN Transaction_Num = @VariableValue
WHEN @VariableName = 'rbOperator' THEN Operator_In = @VariableValue
WHEN @VariableName = 'rbComments' THEN Comments_In = @VariableValue
END ELSE IF @Train = 1 BEGIN
SELECT
Car_ID,
PO_Number,
Vendor,
Shipper,
Commodity,
Date_Weighed_In,
Date_Weighed_Out,
Pile_No AS 'PILe From',
Pile_No1 AS 'Pile To',
Operator_In,
Operator_Out,
Comments_In,
Comments_Out,
Weight_In,
Weight_Out,
Transaction_Num,
Record_time_Stamp
FROM
dbo.Transactions_train
WHERE
(Date_Weighed_IN BETWEEN @BeginDate AND @EndDate) AND
CASE
WHEN @VariableName = 'rbCardID' THEN Car_Id = @VariableValue
WHEN @VariableName = 'rbPONumber' THEN PO_Number = @VariableValue
WHEN @VariableName = 'rbVendor' THEN Vendor = @VariableValue
WHEN @VariableName = 'rbCommodity' THEN Commodity = @VariableValue
WHEN @VariableName = 'rbPileNumber' THEN Pile_No = @PileFrom AND Pile_No1 = @PileTo
WHEN @VariableName = 'rbTransactionNum' THEN Transaction_Num = @VariableValue
WHEN @VariableName = 'rbOperator' THEN Operator_In = @VariableValue
WHEN @VariableName = 'rbComments' THEN Comments_In = @VariableValue
WHEN @VariableName = 'rbRailRoad' THEN Rail_Road = @VariableValue
END
END
你不能那样做你的where声明。。你应该使用AND和OR
WHERE (Date_Weighed_IN BETWEEN @BeginDate AND @EndDate)
AND (
(@VariableName = 'rbCardID' AND Car_Id = @VariableValue)
OR (@VariableName = 'rbPONumber' AND PO_Number = @VariableValue)
OR (@VariableName = 'rbVendor' AND Vendor = @VariableValue)
OR (@VariableName = 'rbCommodity' AND Commodity = @VariableValue)
OR (@VariableName = 'rbPileNumber' AND Pile_No = @PileFrom
AND Pile_No1 = @PileTo )
OR (@VariableName = 'rbTransactionNum' AND Transaction_Num = @VariableValue)
OR (@VariableName = 'rbOperator' AND Operator_In = @VariableValue)
OR (@VariableName = 'rbComments' AND Comments_In = @VariableValue)
OR (@VariableName = 'rbRailRoad' AND Rail_Road = @VariableValue)
)
你不能那样做你的where声明。。你应该使用AND和OR
WHERE (Date_Weighed_IN BETWEEN @BeginDate AND @EndDate)
AND (
(@VariableName = 'rbCardID' AND Car_Id = @VariableValue)
OR (@VariableName = 'rbPONumber' AND PO_Number = @VariableValue)
OR (@VariableName = 'rbVendor' AND Vendor = @VariableValue)
OR (@VariableName = 'rbCommodity' AND Commodity = @VariableValue)
OR (@VariableName = 'rbPileNumber' AND Pile_No = @PileFrom
AND Pile_No1 = @PileTo )
OR (@VariableName = 'rbTransactionNum' AND Transaction_Num = @VariableValue)
OR (@VariableName = 'rbOperator' AND Operator_In = @VariableValue)
OR (@VariableName = 'rbComments' AND Comments_In = @VariableValue)
OR (@VariableName = 'rbRailRoad' AND Rail_Road = @VariableValue)
)
<代码> JAMIDE77 的答案应该做这项工作,但是很多OR可能会让你陷入性能问题,所以我也会考虑使用<代码>动态SQL 来尝试执行一个更小的SQL语句(这是未经测试的,我已经重新格式化以使其更可读): 这样,您的代码就更多了,我认为您应该更快(我不知道引擎是否知道优化所有这些ORs,这可能比使用动态查询可能会损失的性能还要糟糕) 更好的方法是以类型化的方式进行比较。与
@VariableValue
相比,我无法看到所有列的数据类型,但我假设ID和日期不是字符串。如果类型不同于NVARCHAR
,则将为每个不匹配的类型生成隐式强制转换,性能将降低
然而,这将需要使用实体框架(如果这就是您的过程所做的,并且是一个很好的练习的话,这应该不难)或类似的东西来完全重写您的逻辑 >代码> JAMIDE77 的答案应该做这项工作,但是许多OR可能会使你陷入性能问题,所以我也会考虑使用<代码>动态SQL 试图获得一个更小的SQL语句,执行(这是未测试的,我已经重新格式化以使其更可读): 这样,您的代码就更多了,我认为您应该更快(我不知道引擎是否知道优化所有这些ORs,这可能比使用动态查询可能会损失的性能还要糟糕) 更好的方法是以类型化的方式进行比较。与
@VariableValue
相比,我无法看到所有列的数据类型,但我假设ID和日期不是字符串。如果类型不同于NVARCHAR
,则将为每个不匹配的类型生成隐式强制转换,性能将降低
然而,这将需要使用实体框架(如果这就是您的过程所做的,并且是一个很好的练习的话,这应该不难)或类似的东西来完全重写您的逻辑 有关于这些错误是什么的提示吗?我讨厌猜谜游戏。你的案例中有
END
吗?你的@BeginDate
和@EndDate
变量是日期时间,所以你可能应该将它们与NULL进行比较,而不是“”,因为日期不能是空字符串。关于这些错误是什么的提示?我讨厌猜谜游戏。你的案例中有END
吗?你的@BeginDate
和@EndDate
变量都是日期时间,所以你可能应该将它们与NULL进行比较,而不是“”,因为日期不能是一个空字符串,它在几分钟内看起来很糟糕,在几分钟内看起来很糟糕,真的很像动态SQL,请不要误会,但我听说这并不是最佳实践。我尽量让事情变得简单,让后面来的人知道。因此,如果这是一个个人项目,我会完全使用动态SQL,但这是一个公司项目。感谢您提供的动态示例,它非常有帮助,也感谢您提供的其他解决方案。不重复的内容更易于理解和维护。任何看到代码的人都会问(至少我问过)@Train=0或1之间的区别是什么,因为代码几乎相同。不推荐使用动态SQL,因为它很有用,但在某些情况下可能很好。包含许多或多个条件的大型查询更难通过引擎进行优化(也更难被人类理解)。我非常喜欢动态SQL,请不要误解我的意思,但我听说它不是最佳实践。我尽量让事情变得简单,让后面来的人知道。因此,如果这是一个个人项目,我会完全使用动态SQL,但这是一个公司项目。感谢您提供的动态示例,它非常有帮助,也感谢您提供的其他解决方案。不重复的内容更易于理解和维护。任何看到代码的人都会问(至少我问过)@Train=0或1之间的区别是什么,因为代码几乎相同。不推荐使用动态SQL,因为它很有用,但在某些情况下可能很好。包含许多或多个条件的大型查询更难通过引擎进行优化(也更难被人类理解)。