2014-05-14 105 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

相关问题