MSSQL 2008:“案例”的问题 - 声明

时间:2014-02-07 08:36:39

标签: sql reporting-services sql-server-2008-r2 syntax-error case

我遇到了一些麻烦,找不到我的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

注意:如果我在谷歌搜索期间错过了帖子,请不要犹豫,指出来。

感谢您的帮助

1 个答案:

答案 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

但这种方法的主要问题是性能 - 以上将需要完整扫描来确定结果。