SQL Server 2012序列对象

时间:2013-07-03 20:38:11

标签: sql sql-server sql-server-2012 sequences

这是我的示例表,主键是Akey + Bkey的复合键

Akey  Bkey  ItemSequence    
----  ----  ------------
1     1     1
1     5     2
1     7     3
2     7     1
3     2     1
3     3     2

Akey是从SQL 2012 Sequence对象ASequence生成的。在大多数情况下,我一次插入一行,必要时我会调用NEXT VALUE FOR ASequence。但是,我需要从以下语句中插入:

SELECT DENSE_RANK() OVER ( ORDER BY Something) as AKey,
    Bkey, Sequence
FROM TABLEB

NEXT VALUE的OVER子句不能以这种方式工作,因为我需要能够将记录作为SET插入,但每个DENSE_RANK设置只增加一次序列。 所以我们有ALTER SEQUENCE命令,我可以将序列设置为我想要的。对此的警告是它必须是常量并且不接受变量。我的解决方法是:

DECLARE @startingID INT
DECLARE @sql VARCHAR(MAX)
DECLARE @newSeed INT

SET @startingID = NEXT VALUE FOR ASequence

INSERT TABLEA
SELECT DENSE_RANK() OVER ( ORDER BY Something) + @startingID as AKey,
    Bkey, Sequence
FROM TABLEB

SELECT @newSeed = MAX(Akey) FROM TABLEA

SET @sql = ‘ALTER SEQUENCE ASEQUENCE RESTART WITH ‘ + cast(@newSeed+1 as varchar(10))
EXEC(@sql)

在动态SQL中使用DML语句似乎很糟糕。有更好的方法吗?

2 个答案:

答案 0 :(得分:0)

这应该这样做:

INSERT TABLEA
SELECT NEXT VALUE FOR ASequence OVER(ORDER BY Something) as AKey,
    Bkey, Seq
FROM TABLEB

答案 1 :(得分:0)

或者,这是怎么回事:

CREATE TABLEA
(
    GroupID INT,
    AKey INT,
    BKey INT,
    ItemSequence INT, 
    CONSTRAINT PK_TABLEA PRIMARY KEY CLUSTERED 
    (
        GroupID,
        AKey,
        BKey 
    )
)

DECLARE @GroupID INT
SET @GroupID = NEXT VALUE FOR ASequence

INSERT TABLEA
SELECT @GroupID, DENSE_RANK() OVER ( ORDER BY Something) as AKey,
    Bkey, Sequence
FROM TABLEB

如果你需要AKey的值,你可以在这里做GroupID + AKey。