【问题标题】:Can a case statement be used before executing a merge statement?在执行合并语句之前可以使用case语句吗?
【发布时间】:2016-06-17 15:57:42
【问题描述】:

专家,您好。可以使用 case 语句执行或不执行合并语句吗?我是合并功能的新手。在我的情况下,我将这些参数的值传递到我的存储过程中,如下所示:

 @1ID int = NULL
,@1Value float = NULL
,@2ID int = NULL
,@2Value float = NULL
,@3ID int = NULL
,@3Value float = NULL
,@4ID int = NULL
,@4Value float = NULL

AS
--1
MERGE FACT_CookReading AS T
    USING
    (
        SELECT 
             @1ID
            ,@1Value

    ) AS S (
             CookSampleId
            ,ReadingValue

    ) ON (
        T.CookSampleID = S.CookSampleID

    )
    WHEN MATCHED THEN
        UPDATE SET

            ReadingValue = S.ReadingValue

    WHEN NOT MATCHED THEN
        INSERT (
            CookSampleID
            ,ReadingValue

        ) VALUES (
             @1ID
            ,@1Value

        )
;
--2
MERGE FACT_CookReading AS T
    USING
    (
        SELECT 
             @2ID
            ,@2Value

    ) AS S (
             CookSampleId
            ,ReadingValue

    ) ON (
        T.CookSampleID = S.CookSampleID

    )
    WHEN MATCHED THEN
        UPDATE SET

            ReadingValue = S.ReadingValue

    WHEN NOT MATCHED THEN
        INSERT (
            CookSampleID
            ,ReadingValue

        ) VALUES (
             @2ID
            ,@2Value

        )
;

--3
MERGE FACT_CookReading AS T
    USING
    (
        SELECT 
             @3ID
            ,@3Value

    ) AS S (
             CookSampleId
            ,ReadingValue

    ) ON (
        T.CookSampleID = S.CookSampleID


    )
    WHEN MATCHED THEN
        UPDATE SET

            ReadingValue = S.ReadingValue

    WHEN NOT MATCHED THEN
        INSERT (
            CookSampleID
            ,ReadingValue

        ) VALUES (
             @3ID
            ,@3Value

        )
;

--4
MERGE FACT_CookReading AS T
    USING
    (
        SELECT 
             @4ID
            ,@4Value

    ) AS S (
             CookSampleId
            ,ReadingValue

    ) ON (
        T.CookSampleID = S.CookSampleID

    )
    WHEN MATCHED THEN
        UPDATE SET

            ReadingValue = S.ReadingValue

    WHEN NOT MATCHED THEN
        INSERT (
            CookSampleID
            ,ReadingValue

        ) VALUES (
             @4ID
            ,@4Value

        )
;

我遇到的问题是输入的某些参数可能存在空值。这会导致存储过程失败(“无法将值 NULL 插入列...”)。使用此示例,我可能有@1ID/@1Value、@2ID/@2Value 和@3ID/@3Value 的值,但没有@4ID/@4Value。因此,如果@4ID = NULL,我希望处理@4ID 的合并语句不执行。我希望我能做这样的事情:

--4
CASE IF @4ID <> NULL THEN
MERGE FACT_CookReading AS T
    USING
    (
        SELECT 
             @4ID
            ,@4Value

    ) AS S (
             CookSampleId
            ,ReadingValue

    ) ON (
        T.CookSampleID = S.CookSampleID


    )
    WHEN MATCHED THEN
        UPDATE SET

            ReadingValue = S.ReadingValue

    WHEN NOT MATCHED THEN
        INSERT (
            CookSampleID
            ,ReadingValue

        ) VALUES (
             @4ID
            ,@4Value

        )
;

但似乎无法做到。可能有一些更好的方法来处理这个问题。我急切地等待着你的建议。感谢您的宝贵时间!

【问题讨论】:

  • 你的意思是IF @4ID IS NOT NULL MERGECASE 是表达式的一部分,而不是语句。
  • 对不起,我不清楚这一点。我的意思是,如果@4ID 为空,则忽略它。只执行那些参数不为空的合并语句。

标签: sql-server merge


【解决方案1】:

我会将整个内容压缩到一个带有条件更新/插入的 MERGE 中。

正如 Jeroen 指出的那样 - ID 必须是唯一的,否则可能会产生不良影响。

MERGE FACT_CookReading AS T
    USING (SELECT @1ID AS CookSampleId, @1Value AS ReadingValue UNION
           SELECT @2ID, @2Value UNION
           SELECT @3ID, @3Value UNION
           SELECT @4ID, @4Value) AS S 
    ON T.CookSampleID = S.CookSampleID

    WHEN MATCHED AND S.CookSampleID IS NOT NULL THEN
        UPDATE SET
            ReadingValue = S.ReadingValue

    WHEN NOT MATCHED AND S.CookSampleID IS NOT NULL THEN
        INSERT (CookSampleID,ReadingValue) 
        VALUES (S.CookSampleID,S.ReadingValue);

【讨论】:

  • 如果 1) ID 值不是唯一的(尽管很可能,它们将是或应该是)和/或 2) 更新或插入应该允许NULL 值(不是 ID)。
  • 完全正确,我没有考虑过 #1... 将修复 #2,这是一个疏忽。
  • 感谢您抽出宝贵时间发帖!我会查看这个建议,尝试一下,并在下周发布我的结果。应该提一下,上面Jeroen的帖子,确实ID是唯一的,如果值为NULL我们不想插入值。
  • 这比我想象的要容易。 JiggsJedi 的解决方案非常有效。再次感谢您的帮助。现在我可以继续下一个难题了。 :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-07
  • 1970-01-01
  • 2013-08-31
  • 1970-01-01
  • 2013-07-06
  • 1970-01-01
相关资源
最近更新 更多