而不是触发更新主键

时间:2010-07-14 14:04:11

标签: sql-server triggers

长时间读者,第一次海报; - )

我正在实施一个基于旧系统的系统。新系统使用SQL Server 2008,尝试在主表中插入新项时出现问题。这将以两种方式发生:它可以从现有系统(1)导入,也可以在新系统中创建(2)。

如果(1)该项目已经有一个我想保留的ID(int)。在情况(2)中,不会填写ID,并且我想生成一个ID,该ID是表中最大当前值的+1。这当然也适用于插入多行。

据我所知,解决方案是创建一个INSTEAD OF TRIGGER,但我无法弄清楚这是如何完成的。任何人都可以给我一个提示或指出我如何做到这一点?

克里斯

3 个答案:

答案 0 :(得分:1)

如何使用存储过程进行插入,主键作为可选参数。在存储过程中,您可以在未传递主键时设置主键。

我要提醒的是,如果插入旧记录和新记录混合和匹配,您的方案可能会失败,因为新记录将在插入旧记录之前获得旧ID。我建议立即获取旧表的最大ID,并在存储过程设置中将新主键设置为较大值(old max + 1,current table max)

答案 1 :(得分:1)

根据您使用INSTEAD OF触发器的请求,此SQL代码可以帮助您入门。

CREATE TABLE dbo.SampleTable
(
    ID INT,
    SomeOtherValue VARCHAR(100) NULL
)
GO

CREATE TRIGGER dbo.TR_SampleTable_Insert
   ON  dbo.SampleTable
   INSTEAD OF INSERT
AS 
BEGIN

    SET NOCOUNT ON;

    -- Inserting rows with IDs
    INSERT INTO dbo.SampleTable (
        ID, 
        SomeOtherValue)
    SELECT 
        ID, 
        SomeOtherValue
    FROM
        Inserted    
    WHERE
        ID IS NOT NULL

    -- Now inserting rows without IDs
    INSERT INTO dbo.SampleTable (
        ID, 
        SomeOtherValue)
    SELECT 
        (SELECT ISNULL(MAX(ID), 0) FROM dbo.SampleTable) 
            + ROW_NUMBER() OVER(ORDER BY ID DESC),
        SomeOtherValue
    FROM
        Inserted
    WHERE
        ID IS NULL

END
GO

INSERT INTO dbo.SampleTable
SELECT 1, 'First record with id'
UNION
SELECT NULL, 'First record without id'
UNION
SELECT 2, 'Second record with id'
UNION
SELECT NULL, 'Second record without id'
GO

SELECT * FROM dbo.SampleTable
GO

答案 2 :(得分:0)

其他人已经向您展示了如何编写此类触发器。

另一种(通常是推荐的)方法是将两个ID存储在新数据库中。每条记录在新系统中获取新ID(通过IDENTITY列或其他方式)。此外,如果记录是从另一个系统导入的,则它具有关联的OriginSystem和OriginID。这样您就可以保留旧ID以供参考。这种方法具有额外的好处,即能够支持新系统从例如导入数据。与其他系统合并或交换数据时。