2016-10-24 60 views
0

我遇到了问题,我想从存储过程中获取数据。该过程用于插入和更新记录,并确定在调用时设置哪些参数。我这里的例子假设DATE类型参数的默认值为NULL,即它们没有被传入sp。我已经打破了代码分解成小部分来解决,而不是包括整个程序代码,如下所示:SQL在存储过程中嵌套的Case语句

-- these would be sp parameters 
declare @CustomerId int = 15 
declare @Indicator varchar(5) = 'Yes' 
declare @ProjectTypeId tinyint = 1 
declare @FutureEffectiveDate as date = null 

     SELECT 
      CASE @FutureEffectiveDate 
       WHEN NULL THEN      
        CASE @Indicator 
         WHEN 'Yes' THEN 
          -- can only be 1, 2 or 3 to return relevant date 
          CASE @ProjectTypeId 
           WHEN 1 THEN DI.[NextFormalEffectiveDate] 
           WHEN 2 THEN DI.[NextInterimEffectiveDate] 
           WHEN 3 THEN DI.[NextAccountingEffectiveDate]        
          END 
         -- data should be NULL if @Indicator not 'Yes' 
         ELSE NULL 
        END 
       ELSE @FutureEffectiveDate 
      END AS [FutureEffectiveDate] 
     FROM 
      [_Staging].[DataImport_2] AS DI 
     JOIN 
      [CustomerView] AS CV ON CV.[CustomerNumber] = DI.[BillingInvoiced] 
     JOIN 
      [ProjectType] AS PT ON PT.[ProjectType] = DI.[ProjectType] 
     WHERE 
      CV.[CustomerID] = @CustomerId AND 
      PT.[ProjectTypeID] = @ProjectTypeId 

这样的想法是,对于一个字段包含文本“是”的记录,基于该记录的项目类型,它选择三个日期中的一个。如果该字段不是'是',那么它应该返回NULL,忽略项目类型。如果date参数不为null,那么它应该简单地返回传入的参数。结果作为列“FutureEffectiveDate”返回。对于我有的示例数据,我期望返回一个日期,因为相关字段为'是',并且NextFormalEffectiveDate列有一个值(因为项目类型为1)。
奇怪的是,如果排除外部CASE语句,它就会起作用。所以问题是基于DATE参数确定要做什么,但我不明白为什么外部CASE语句会破坏结果。

+0

你知道你传递NULL作为你的约会参数的正确方式进行比较?我经常以空字符串的形式传递,并且人们认为它实际上是1900-01-01。 –

+0

是的,这里的意图是我的UI和数据导入过程都可以使用这个sp,所以我没有写两个过程,而是在签名中默认参数为null,所以如果它们没有被传入,那么sp可以从数据库读取它们并执行UPDATE,但是如果填充,它们将用作INSERT语句的一部分。 – MartinS

回答

4

您在CASE语句中检查@FutureEffectiveDate的方式是错误的。这里是一个小型演示

declare @FutureEffectiveDate as date = null 

Select Case @FutureEffectiveDate when NULL then 1 else 0 end 

上述查询将导致0。因为上面的CASE语句验证输入表达式,如@FutureEffectiveDate = NULL将失败。 NULL应该使用IS操作

这里是比较NULL

SELECT CASE 
     WHEN @FutureEffectiveDate IS NULL THEN 
      CASE .. 
+0

我试过了CASE @FutureEffectiveDate WHEN是NULL,但得到了一个语法错误,第一次看了你的演示,看不出有什么不同,但是在WHEN中有参数,就像你说的那样,确实解决了问题。这种格式只有在与NULL比较时才有必要?在其他CASE语句中,我使用了格式CASE参数WHEN X THEN ... END,并且这些参数按预期工作。 – MartinS