我遇到了一些麻烦,找不到我的SQL问题的解决方案。我试过谷歌但到目前为止我的搜索没有给我任何令人满意的结果。
我有一个包含两个参数的SSRS报告:
@SupplierId NVARCHAR (May contain NULL)
@EmployeeId NVARCHAR (May contain NULL)
我的原始查询检索了去年服务的所有员工:
SELECT Name, Surname from dbo.Employee Where Employee.DateInService > DATEADD(year,-1,GETDATE())
现在我想使用以下逻辑将这些参数添加到查询中。
备注这是伪SQL:
SELECT
...
FROM ...
WHERE Employee.DateInService > DATEADD(year,-1,GETDATE()) AND
IF (LEN(RTRIM(@SupplierId)) = 0 Or @SupplierID IS NULL ) THEN
dbo.Employee.EmployeeId = @EmployeeId
Else
dbo.Employee.SupplierId = @SupplierId
我的搜索主持人引导我查看Case
声明。我做了一个包含语法错误的查询(显然)。我的基本查询:
SELECT
...
FROM ...
WHERE Employee.DateInService > DATEADD(year,-1,GETDATE()) AND
CASE WHEN (LEN(RTRIM(@SupplierId)) = 0) THEN
dbo.Employee.EmployeeId = @EmployeeId
Else
dbo.Employee.SupplierId = @SupplierId
错误:'='附近的语法错误。
问题1:为什么他会在'='附近发出错误?
问题2:如何正确实施以下内容:
CASE WHEN (LEN(RTRIM(@SupplierId)) = 0 "Or @SupplierId is null" ) THEN
而不是
CASE WHEN (LEN(RTRIM(@SupplierId)) = 0) Then dbo.Employee.EmployeeId = @EmployeeId
WHEN (@SupplierId IS NULL) Then dbo.Employee.EmployeeId = @EmployeeId
ELSE dbo.Employee.EmployeeId = @EmployeeId END
注意:如果我在谷歌搜索期间错过了帖子,请不要犹豫,指出来。
感谢您的帮助
答案 0 :(得分:2)
您无法使用CASE
更改实际查询谓词 - 根据@SupplierId
的值,有2个不同的查询。您可以按如下方式有条件地应用过滤器(我假设@SupplierId
= null流与空白分支相同:
SELECT
...
FROM ...
WHERE Employee.DateInService > DATEADD(year,-1,GETDATE())
AND
(
(dbo.Employee.EmployeeId = @EmployeeId
AND (LEN(RTRIM(@SupplierId)) = 0 OR @SupplierId IS NULL))
OR
(dbo.Employee.SupplierId = @SupplierId AND LEN(RTRIM(@SupplierId)) > 0)
)
虽然这可能容易导致查询计划嗅探相关的性能问题,但在这种情况下,您可能需要考虑另一种方法,例如:使用parameterized dynamic sql来构建和执行sql,因为查询中有2个不同的流程。
修改强>
根据Ypercube上面的评论,为了提供谓词所需的布尔结果,如果你能找到一个 hack 的解决方法就是找到一种方法来从每个{项目中投射一个COMMON标量{1}} .. CASE
行,然后对标量进行比较。在下面的示例中,投射是/否标志。
WHEN
但这种方法的主要问题是性能 - 以上将需要完整扫描来确定结果。