2014-05-14 169 views
1

我有一個ProductsAttributesValues表具有,插入或更新或刪除數據從表值參數

Id ProductId AttributeId Value ORDER 
------------------------------------------------- 

與屬性(同樣產品編號/屬性Id)可以有多個值,但具有不同的訂單的產品。我有一個類型,

CREATE TYPE [dbo].[ProductsAttributesValuesType] AS TABLE 
(
    [AttributeId] [INT], 
    [Value] [NVARCHAR](MAX) 
) 

我傳遞這ProductsAttributesValuesType在我的存儲過程與產品編號參數表值參數。現在我所需要的東西似乎很簡單,但我被困住了。 ProductsAttributesValuesType中的信息來自用戶界面。所以,

1)如果一個值爲空或空或空白,那麼我需要什麼也不做,並刪除所有現有的記錄從ProductsAttributesValues具有相同的ProductId/AttributeId。 2)如果一個值不爲空或非空或非空白,則可能有單個值或多個值(ProductsAttributesValuesType中的多個記錄)。如果存在單個值,如果不存在現有值,則需要插入,如果存在值,則更新。如果有多個值(ProductsAttributesValuesType中有多個記錄),則需要在沒有現有值的情況下插入所有值,如果存在值,則需要更新/插入。

一種方法是簡單地刪除具有相同ProductId/AttributeId的所有ProductsAttributesValues表。然後插入非空值的值。但我認爲這不是非常有效。

更新:目前,我首先刪除所有多值屬性值。接下來,我將刪除其中值爲空的所有屬性值。接下來,我插入/更新單個值屬性值。接下來,我插入多個屬性值。

+0

看看'MERGE'。 –

+0

我知道MERGE,但我被卡住了。你能解決這個問題嗎? – user960567

+0

包括您到目前爲止所嘗試的內容以及源代碼/結果的示例集合。 – sarin

回答

3

避免使用MERGE語句,把它分解到三個聲明,如下

CREATE Procedure Upserting_To_ProductsAttributesValues 
@ProductsAttributesValuesType [dbo].[ProductsAttributesValuesType] READONLY 
AS 
BEGIN 
SET NOCOUNT ON; 
BEGIN TRY 
    BEGIN TRANSACTION; 

-- Delete values 
    DELETE FROM ProductsAttributesValues 
    FROM ProductsAttributesValues T INNER JOIN @ProductsAttributesValuesType P 
    ON T.AttributeId = P.AttributeId 
    WHERE P.Value IS NULL OR RTRIM(LTRIM(P.Value)) = '' 

-- Update Statement 
UPDATE T 
SET T.Value = P.Value 
FROM ProductsAttributesValues T INNER JOIN @ProductsAttributesValuesType P 
ON T.AttributeId = P.AttributeId 

-- Insert Statement 
INSERT INTO ProductsAttributesValues (AttributeId, Value) 
SELECT AttributeId, Value 
FROM @ProductsAttributesValuesType P 
WHERE NOT EXISTS (SELECT 1 
        FROM ProductsAttributesValues 
        WHERE AttributeId = P.AttributeId) 

    COMMIT TRANSACTION; --<-- If nothing went wrong 
END TRY 

BEGIN CATCH 


    -- Now make use of ERROR Functions to get detailed information 
    -- about the error, these functions are only allowed in catch block 

SELECT ERROR_MESSAGE() AS [ERROR_MESSAGE] 
     ,ERROR_LINE() AS [ERROR_LINE] 
     ,ERROR_NUMBER() AS [ERROR_NUMBER] 
END CATCH 

END 

的,我建議,以避免合併請看這篇文章亞倫理由把它包在同一個交易Bertrand Use Caution with SQL Server's MERGE Statement

+0

謝謝阿里,但我有很多值。 – user960567

+0

這應該工作,但在DELETE部分中,您想要說LEFT JOIN而不是INNER JOIN – Yuri

相關問題