3

最初の主キー列に新しいエントリが追加されたときに、テーブルの 2 番目の主キー列を自動的にインクリメントする方法を見つけようとしています。ここでの例が最適だと思うので、ここに行きます。

テーブルがあるとします:

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 に答える