sql - MSSQL 2008 : Problems with the 'Case' - statement

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

我在为SQL问题找到解决方案时遇到了一些麻烦。我已经尝试过使用google,但到目前为止,我的搜索都没有给我任何令人满意的结果。

我有一个带有两个参数的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

注意:如果我在Google搜索过程中错过了任何帖子,请随时指出。

谢谢你的帮助

最佳答案

您无法像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的评论,为了提供谓词所需的 bool(boolean) 结果,如果可以找到一种解决方法,那就是找到一种方法来从每个CASE .. WHEN行中投影一个普通标量,然后对标量。在下面的示例中,投影一个yes/no标志。
SELECT * FROM dbo.Employee 
WHERE
    CASE 
        WHEN (LEN(RTRIM(@SupplierId)) = 0 OR @SupplierId IS NULL) 
          THEN CASE WHEN dbo.Employee.EmployeeId = @EmployeeId THEN 1 ELSE 0 END
          ELSE CASE WHEN dbo.Employee.SupplierId = @SupplierId THEN 1 ELSE 0 END
    END = 1;

但是这种方法的最大问题是性能-上面的操作将需要全面扫描才能确定结果。

关于sql - MSSQL 2008 : Problems with the 'Case' - statement,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21622894/

相关文章:

sql - Mysql查询以便更好地排序结果

xml - Microsoft.Reporting.* 与 XML/XSLT

T SQL-触发器而不是更新语句中不包含更新列

sql - 使用 Clojure 连接到 Microsoft SQL Server

mysql - SQL错误1064 建表失败

sql - 在 SSRS 中调整子报表的大小

sql-server - 报告服务 (ssrs) 提示输入用户名/密码

sql-server - SQL Server 2008 R2 : Concatenate alias name with column value

search - SQL Server 在 nvarchar 和 ntext 中搜索

sql - PLSQL CASE WHEN 条件