基于变量值在UPDATE语句中使用什么WHERE子句

时间:2017-08-23 17:51:50

标签: sql-server tsql

我有一个UPDATE语句,我设置了一个变量@peims2017SnapshotDate,根据其值,我需要确定要使用哪个WHERE子句。

我在@ISTRUE = 1之后在SQL Server 2014中收到IntelliSense错误,其中WHERE一词的语法错误不正确。

我确信有更好的方法来解决这个问题但我在这里的杂草。

这是我的SQL代码:

    UPDATE t
    SET t.Enddate = CONVERT(VARCHAR(10), DATEADD(day, -1, s.Effective_Date),101),
        t.LastUpdated = GETDATE(),
        t.UpdatedAppType = 'HHS_update',
        t.DataSource = 'HHS' 
    FROM dbo.vw_HHSurvey s
    INNER JOIN dbo.Focus_Econ_Disadvantaged_Last_Snapshot t
        ON s.CustomerID = t.StudentID
        AND s.SiteID = t.Location
    SET @ISTRUE = (SELECT CASE WHEN CAST(t.StatusEffectiveDate as date) > @peims2017SnapshotDate THEN 1 ELSE 0 END) 
    IF @ISTRUE = 1  
        WHERE CAST(t.StatusEffectiveDate as date) > @peims2017SnapshotDate) 
        AND CONVERT(date, s.Effective_Date, 101) > CONVERT(date, t.StatusEffectiveDate, 101)
        AND ((t.[Status] = 'Paid' AND s.[Status] != 'PAID') 
            OR (t.[Status] = 'Reduced' AND s.[Status] = 'FREE'))
    IF @ISTRUE = 0 
        WHERE CONVERT(date, s.Effective_Date, 101) > CONVERT(date, t.StatusEffectiveDate, 101)
        AND ((t.[Status] = 'Paid' AND s.[Status] != 'PAID') 
            OR (t.[Status] = 'Reduced' AND s.[Status] = 'FREE'))

4 个答案:

答案 0 :(得分:3)

SET过滤器中间不能有ON个变量。

尝试以下方法:

UPDATE t
SET t.Enddate = CONVERT(VARCHAR(10), DATEADD(day, -1, s.Effective_Date),101),
    t.LastUpdated = GETDATE(),
    t.UpdatedAppType = 'HHS_update',
    t.DataSource = 'HHS' 
FROM dbo.vw_HHSurvey s
INNER JOIN dbo.Focus_Econ_Disadvantaged_Last_Snapshot t
    ON s.CustomerID = t.StudentID
    AND s.SiteID = t.Location
WHERE (
    CAST(t.StatusEffectiveDate as date) > @peims2017SnapshotDate 
    AND CONVERT(date, s.Effective_Date, 101) > CONVERT(date, t.StatusEffectiveDate, 101)
    AND ((t.[Status] = 'Paid' AND s.[Status] != 'PAID') 
        OR (t.[Status] = 'Reduced' AND s.[Status] = 'FREE')
        )
    OR
    NOT(CAST(t.StatusEffectiveDate as date) > @peims2017SnapshotDate)
    AND CONVERT(date, s.Effective_Date, 101) > CONVERT(date, t.StatusEffectiveDate, 101)
    AND ((t.[Status] = 'Paid' AND s.[Status] != 'PAID') 
        OR (t.[Status] = 'Reduced' AND s.[Status] = 'FREE')
        )
    )

答案 1 :(得分:0)

  UPDATE t
     SET t.Enddate = CONVERT(VARCHAR(10), DATEADD(day, -1, s.Effective_Date),101),
         t.LastUpdated = GETDATE(),
         t.UpdatedAppType = 'HHS_update',
         t.DataSource = 'HHS' 
    FROM dbo.vw_HHSurvey s
   INNER JOIN dbo.Focus_Econ_Disadvantaged_Last_Snapshot t ON s.CustomerID = t.StudentID AND s.SiteID = t.Location
   WHERE 1 = CASE
              WHEN CAST(t.StatusEffectiveDate as date) > @peims2017SnapshotDate
                 THEN CASE
                       WHEN     CAST(t.StatusEffectiveDate as date) > @peims2017SnapshotDate) 
                            AND CONVERT(date, s.Effective_Date, 101) > CONVERT(date, t.StatusEffectiveDate, 101)
                            AND (   (t.[Status] = 'Paid'    AND s.[Status] != 'PAID') 
                                 OR (t.[Status] = 'Reduced' AND s.[Status] = 'FREE')) then 1
                       ELSE 0
                      END
              ELSE CASE
                    WHEN     CONVERT(date, s.Effective_Date, 101) > CONVERT(date, t.StatusEffectiveDate, 101)
                         AND (   (t.[Status] = 'Paid' AND s.[Status] != 'PAID') 
                              OR (t.[Status] = 'Reduced' AND s.[Status] = 'FREE')) then 1
                    ELSE 0
                   END
             END

答案 2 :(得分:0)

由于你的某些条件在@ISTRUE为1或0时都有效,所以我简化了一下。相反,请务必检查结果是否相同。

DECLARE @ISTRUE  int, @peims2017SnapshotDate datetime
SET @peims2017SnapshotDate = getdate()-- note this was placed here just to see if the syntax passed, use whatever declaration and population you have for this variable
SET @ISTRUE = (SELECT
    CASE
    WHEN CAST(t.StatusEffectiveDate as date) > @peims2017SnapshotDate 
    THEN 1 ELSE 0 END);

UPDATE t
SET t.Enddate = CONVERT(VARCHAR(10), DATEADD(day, -1, s.Effective_Date),101),
    t.LastUpdated = GETDATE(),
    t.UpdatedAppType = 'HHS_update',
    t.DataSource = 'HHS' 
FROM dbo.vw_HHSurvey s
INNER JOIN dbo.Focus_Econ_Disadvantaged_Last_Snapshot t
    ON s.CustomerID = t.StudentID
    AND s.SiteID = t.Location
WHERE CONVERT(date, s.Effective_Date, 101) > CONVERT(date, t.StatusEffectiveDate, 101)
    AND (
            (t.[Status] = 'Paid' AND s.[Status] != 'PAID')      
            OR (t.[Status] = 'Reduced' AND s.[Status] = 'FREE')
        )
    and (
            (
            @ISTRUE = 1  
            AND CAST(t.StatusEffectiveDate as date) > @peims2017SnapshotDate 
            )
            OR @ISTRUE = 0
        );

答案 3 :(得分:0)

虽然其他人已经指出你不能在UPDATE语句的中间使用SET,并且你通常必须做两次检查并在备选之间添加OR或者使用CASE更有创意,这里是你的查询进一步简化由于WHERE条件对于两种条件完全相同,唯一的区别是如果条件为TRUE,则进行额外检查:

UPDATE t
SET t.Enddate = CONVERT(VARCHAR(10), DATEADD(day, -1, s.Effective_Date),101),
    t.LastUpdated = GETDATE(),
    t.UpdatedAppType = 'HHS_update',
    t.DataSource = 'HHS' 
FROM dbo.vw_HHSurvey s
INNER JOIN dbo.Focus_Econ_Disadvantaged_Last_Snapshot t
ON s.CustomerID = t.StudentID
AND s.SiteID = t.Location
AND CONVERT(date, s.Effective_Date, 101) > CONVERT(date, t.StatusEffectiveDate, 101)
AND ((t.[Status] = 'Paid' AND s.[Status] != 'PAID') 
    OR (t.[Status] = 'Reduced' AND s.[Status] = 'FREE'))
AND (CAST(t.StatusEffectiveDate as date) > @peims2017SnapshotDate AND CAST(t.StatusEffectiveDate as date) > @peims2017SnapshotDate
    OR CAST(t.StatusEffectiveDate as date) <= @peims2017SnapshotDate)