如何使用SQL Merge更新或插入记录

时间:2016-12-22 06:41:54

标签: sql-server stored-procedures

我有一个Windows窗体应用程序,如果它已经存在,则需要编辑现有记录,如果不存在则创建它。我正在使用SQL Server 2008 R2。我的应用程序从各种表中读取数据,如果记录已存在,则包括输出表的ID字段。

如果正在创建新记录,则ID字段为空。 ID字段是主键,目标表的标识(自动增量)字段。

我使用MERGE创建了一个存储过程,希望能创建新记录或更新现有记录。更新部分正在运行,但我无法弄清楚在创建时如何处理ID字段。

进行更新时,我传入一个ID参数,并找到现有记录。显然,如果它是一个新记录我还没有ID,但我不能将该参数保留,或者我得到一个未指定的变量错误,如你所料。

这是我的存储过程。我只是在这里咆哮错误的树 某处?

我是否应该创建两个存储过程并调用更新(如果有)和ID和调用创建(如果我没有和ID?)

感谢您的帮助。

USE [Insurance]
GO

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

ALTER PROCEDURE [dbo].[CreateModifyValuation]

-- Add the parameters for the stored procedure here
@ValuationID int,
@OwnersCorporationID int,
@ValDate    datetime,
@ValuerID   int,
@Amount     money,
@Printed    bit,
@Approved   bit,
@Notes      varchar(max),
@MultiplierValue money,
@MultiplierClass    char(10),
@Adjustment money,
    @SubmittedDate datetime

AS
BEGIN
    -- SET NOCOUNT ON added to prevent extra result sets from
    -- interfering with SELECT statements.
    SET NOCOUNT ON;
-- Insert statements for procedure here

Merge Valuation as Target
USING (Select   
            @ValuationID,
            @OwnersCorporationID, 
            @ValDate,   
            @ValuerID, 
            @Amount, 
            @Printed, 
            @Approved, 
            @Notes, 
            @MultiplierValue, 
            @MultiplierClass, 
            @Adjustment,
            @SubmittedDate
        )
        As Source(
            ValuationID,
            OwnersCorporationID, 
            ValDate,    
            ValuerID, 
            Amount, 
            Printed, 
            Approved, 
            Notes, 
            MultiplierValue, 
            MultiplierClass, 
            Adjustment,
            SubmittedDate
        )

ON Source.ValuationID = Target.ValuationID
WHEN MATCHED THEN
UPDATE SET 
    Target.OwnersCorporationID = Source.OwnersCorporationID,
    Target.ValDate = Source.ValDate,
    Target.ValuerID = Source.ValuerID,
    Target.Amount = Source.Amount,
    Target.Printed = Source.Printed,
    Target.Approved = Source.Approved,
    Target.Notes = Source.Notes,
    Target.MultiplierValue = Source.MultiplierValue,
    Target.MultiplierClass = Source.MultiplierClass,
    Target.Adjustment = Source.Adjustment,
    Target.SubmittedDate = Source.SubmittedDate

WHEN NOT MATCHED BY Target THEN
INSERT (
            OwnerscorporationID,
            ValDate,
            ValuerID,
            Amount,
            Printed,
            Approved,
            Notes,
            MultiplierValue,
            MultiplierClass,
            Adjustment,
            SubmittedDate
        )
VALUES  (
            Source.OwnersCorporationID,
            Source.ValDate,
            Source.ValuerID,
            Source.Amount,
            Source.Printed,
            Source.Approved,
            Source.Notes,
            Source.MultiplierValue,
            Source.MultiplierClass,
            Source.Adjustment,
            Source.SubmittedDate    
        );

END

1 个答案:

答案 0 :(得分:0)

我觉得自己被骗了,但它只有一条线,所以它有多糟糕:)

在我的SQL中,我在" SET NOCOUNT ON之前添加了这一行;"

(如果我在SET NOCOUNT ON之后输入,我会收到语法错误,这很有趣)

if (@ValuationID = 0) set @ValuationID = null

然后在我的C#代码中,我将ID设置为0以获取新记录,并且在经过几次测试后似乎可以正常工作。可能有一种更好的方法可以做到这一点,但就像生活中的大多数事情一样,一旦它起作用就停止寻找 再次感谢那些评论的人。

大卫