Sql server 主键更改的表值参数

Sql server 主键更改的表值参数,sql-server,composite-primary-key,table-valued-parameters,Sql Server,Composite Primary Key,Table Valued Parameters,我刚刚开始在SQLServer2008中使用表值参数来更新表。基本上,我创建了一个用户定义的表类型映射,逐列映射到一个现有的表,并将其用作表值参数,将数据传递给服务器进行删除、更新和插入。在大多数情况下,这很好。然而,对于具有复合主键的表,当部分键被更改时,这种方法将失败,因为tvp只包含一组键值(当前或原始)。我的问题是,处理此类案件的最佳方式是什么?是否必须在表类型定义中添加第二组主键列 一个简化的例子: 表: 现在的问题是如何使用表值参数(tvp_Prices)将更改保存回服务器?表值参数

我刚刚开始在SQLServer2008中使用表值参数来更新表。基本上,我创建了一个用户定义的表类型映射,逐列映射到一个现有的表,并将其用作表值参数,将数据传递给服务器进行删除、更新和插入。在大多数情况下,这很好。然而,对于具有复合主键的表,当部分键被更改时,这种方法将失败,因为tvp只包含一组键值(当前或原始)。我的问题是,处理此类案件的最佳方式是什么?是否必须在表类型定义中添加第二组主键列

一个简化的例子: 表:


现在的问题是如何使用表值参数(tvp_Prices)将更改保存回服务器?

表值参数用于通过参数将多行数据传递给存储过程等。在您的情况下,用例可能是下一个:

CREATE TYPE [dbo].[tvp_Prices] AS TABLE(
    [ID] [int] NOT NULL,
    [Date] [smalldatetime] NOT NULL,
    [Value] [float] NOT NULL
);

CREATE TABLE [dbo].[Prices](
    [ID] [int] NOT NULL PRIMARY KEY,
    [Date] [smalldatetime] NOT NULL PRIMARY KEY,
    [Value] [float] NOT NULL,
    CONSTRAINT [PK_Prices] PRIMARY KEY CLUSTERED 
    (
        [ID] ASC,
        [Date] ASC
    )
);

CREATE PROC dbo.use_Prices
(
    @prices [dbo].[tvp_Prices] READONLY
)
AS BEGIN
    INSERT INTO [dbo].[Prices] ([ID], [Date], [Value])
    SELECT * FROM @prices;
END


-- usage ---------------------------------

DECLARE
    @prices [dbo].[tvp_Prices];

Insert Into  @prices Values (1, '1/1/2015', 1.2)
Insert Into  @prices Values (1, '1/2/2015', 1.3)
Insert Into  @prices Values (2, '1/1/2015', 1.4)
Insert Into  @prices Values (2, '1/2/2015', 1.5)

SELECT * FROM [dbo].[Prices]

EXEC dbo.use_Prices @prices;

SELECT * FROM [dbo].[Prices]
结果

ID  Date    Value
-----------------------------
-


更新示例 输出

ID  Date                Value
-----------------------------
1   2015-01-01 00:00:00 1.2
1   2015-01-02 00:00:00 1.3
2   2015-01-01 00:00:00 1.4
2   2015-01-02 00:00:00 1.5


ID  Date                Value
-----------------------------
1   2015-01-01 00:00:00 10.1
1   2015-01-02 00:00:00 11.11
2   2015-01-01 00:00:00 1.4
2   2015-01-02 00:00:00 1.5

不清楚你所说的“这种情况”是什么意思?请添加更多详细信息并显示您已经完成的工作。您能否添加冲突发生的示例?我一点也不清楚你的问题是什么。谢谢。对于insert,我知道这样做很好。但是,在我的简化示例中,如果主键的一部分发生了更改,那么如何更新呢?更新主键的一部分是一个非常糟糕的主意。永远不要更新主键。这绝对是一个无用的想法,因为主键是表中每一行的唯一标识符,如果您更改它,就像删除这一行并插入另一行一样。这个“问题”与未来在alland使用TVP无关:谢谢。虽然您提供的代码对我帮助不大,但您关于更新部分主键的评论是个坏主意,确实对我有所帮助。我有一种感觉,这可能不是理想的方式,你的评论说服我采取不同的方法。
ID  Date                Value
-----------------------------
1   2015-01-01 00:00:00 1.2
1   2015-01-02 00:00:00 1.3
2   2015-01-01 00:00:00 1.4
2   2015-01-02 00:00:00 1.5
CREATE PROC dbo.use_UpdatePrices
(
    @prices [dbo].[tvp_Prices] READONLY
)
AS BEGIN
    -- update values by the PK
    UPDATE p
    SET
        p.[Value] = p1.[Value]
    FROM [dbo].[Prices] p
    JOIN @prices p1 ON p1.ID = p.[ID]
    AND p1.[Date] = p.[Date];
END

Truncate table [dbo].[Prices]

Insert Into  [dbo].[Prices] Values (1, '1/1/2015', 1.2)
Insert Into  [dbo].[Prices] Values (1, '1/2/2015', 1.3)
Insert Into  [dbo].[Prices] Values (2, '1/1/2015', 1.4)
Insert Into  [dbo].[Prices] Values (2, '1/2/2015', 1.5)

-- usage -----------------------------------
DECLARE
@prices [dbo].[tvp_Prices];

-- values to update
Insert Into  @prices Values (1, '1/1/2015', 10.10) 
Insert Into  @prices Values (1, '1/2/2015', 11.11)

SELECT * FROM [dbo].[Prices]

EXEC dbo.use_UpdatePrices @prices;

SELECT * FROM [dbo].[Prices]
ID  Date                Value
-----------------------------
1   2015-01-01 00:00:00 1.2
1   2015-01-02 00:00:00 1.3
2   2015-01-01 00:00:00 1.4
2   2015-01-02 00:00:00 1.5


ID  Date                Value
-----------------------------
1   2015-01-01 00:00:00 10.1
1   2015-01-02 00:00:00 11.11
2   2015-01-01 00:00:00 1.4
2   2015-01-02 00:00:00 1.5