3

当为第一个主键列添加新条目时,我正在尝试找到一种方法来自动增加表中的第二个主键列。我想这里最好有一个例子,所以这里有。

假设我有一张桌子:

CREATE TABLE T
(
     SecNum INT NOT NULL,
     EntryID INT NOT NULL,
     Value FLOAT,
) CONSTRAINT [PK_T] PRIMARY KEY CLUSTERED 
(
    [SecNum] ASC,
    [EntryID] ASC
)

我会运行以下语句:

INSERT INTO T (SecNum, Value) VALUES (0, 10)

我的表应该如下所示:

SECNUM | ENTRYID | VALUE
-------------------------
   0         0       10

我会运行以下语句:

INSERT INTO T (SecNum, Value) VALUES (0, 10)

我的表应该如下所示:

SECNUM | ENTRYID | VALUE
-------------------------
   0         0       10
   0         1       10

我会运行以下语句:

INSERT INTO T (SecNum, Value) VALUES (1, 20)

我的表应该如下所示:

SECNUM | ENTRYID | VALUE
-------------------------
   0         0       10
   0         1       10
   1         0       20
4

4 回答 4

2

这可以使用INSTEAD OF触发器:

CREATE TRIGGER TriggerName
ON T
INSTEAD OF INSERT
AS
    -- THIS TOP BIT IS OPTIONAL, IT WILL ALLOW ENTRY ID TO BE OVERRIDDEN IF 
    -- IT IS SUPPLIED TO THE INSERT AND WILL NOT VIOLATE THE PRIMARY KEY
    IF NOT EXISTS 
        (   SELECT  1
            FROM    T
                    INNER JOIN inserted i
                        ON i.SecNum = T.secNum
                        AND i.EntryID = T.EntryID
            UNION
            SELECT  1
            FROM    inserted
            WHERE   EntryID IS NULL
        )
        BEGIN
            INSERT T (SecNum, EntryID, Value)
            SELECT  SecNum, EntryID, Value
            FROM    inserted
        END
    ELSE
    -- IF OVERRIDE ABILITY IS NOT REQUIRED JUST USE THE BELOW INSERT
        BEGIN
            INSERT T (SecNum, EntryID, Value)
            SELECT  i.SecNum, COALESCE(LastID, 0), i.Value
            FROM    inserted I
                    LEFT JOIN 
                    (   SELECT  SecNum, MAX(T.EntryID) + 1 [LastID]
                        FROM    T
                        GROUP BY SecNum
                    ) T
                        ON T.SecNum = i.SecNum

        END

这里的例子

然而,这不是很优雅。值得一问是否真的有必要?您能否摆脱使用代理主键并用于动态ROW_NUMBER()创建条目 ID 的情况?

于 2012-06-08T15:38:21.203 回答
1

您的问题可以通过使用instead of insert触发器来解决

 create trigger Trigger1 on T INSTEAD OF INSERT
 as
 begin                                  
       insert into T(SecNum,EntryID,Value)
       select SecNum,
             (select count(*) from T where SecNum = i.SecNum) as EntryID, 
             value 
       from inserted i
 end
于 2012-06-08T17:31:12.693 回答
1

像这样的东西怎么样:

INSERT INTO T (SecNum, Value, EntryId)
SELECT 0, 10, count(*)
FROM T WHERE SecNum = 0

它不是最干净的解决方案,而且性能也很差。但它应该完成工作。

于 2012-06-08T19:54:34.910 回答
1

这是如何在不将值存储在表中的情况下执行此操作(我不确定您为什么要存储它)

桌子

DECLARE @T TABLE
    (
      SecNum INT NOT NULL,
      EntryID INT,
      Value FLOAT
    )

数据

INSERT  INTO @T
        ( SecNum, Value )
VALUES  ( 0, 10 )
INSERT  INTO @T
        ( SecNum, Value )
VALUES  ( 0, 10 )
INSERT  INTO @T
        ( SecNum, Value )
VALUES  ( 1, 20 )

询问

SELECT  SecNum,
        ROW_NUMBER() OVER ( PARTITION BY value ORDER BY Value ) - 1 AS EntryID,
        Value
FROM    @T

结果

SecNum  EntryID Value
0          0    10
0          1    10
1          0    20

如果 EntryID 随 SecNum AND Value 发生变化,请使用以下查询:

SELECT  SecNum,
        ROW_NUMBER() OVER ( PARTITION BY Value,SecNum ORDER BY Value, SecNum ) - 1 AS EntryID,
        Value
FROM    @t

结果 2

SecNum  EntryID Value
0           0   10
0           1   10
1           0   10
1           0   20
于 2012-06-08T20:04:01.607 回答