2013-07-03 43 views
2

這是我的試樣臺,主鍵是由SQL 2012 Sequence對象ASequence生成的A密鑰+ B密鑰SQL Server 2012的序列對象

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

A密鑰的組合密鑰。在大多數情況下,我一次插入一行,必要時我稱之爲序列的下一個值。不過,我需要從類似的聲明做插入:

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

下一個值的OVER子句,因爲我需要能夠插入記錄爲一組,但只增加序列一次每不起作用這種方式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) 

似乎在Dynamic SQL中有這樣的DML語句可怕。有一個更好的方法嗎?

+0

弗拉德提供的解決方案是要走的路。但是,如果將來必須使用動態SQL,請務必使用[sp_executesql](http://msdn.microsoft.com/zh-cn/library/ms188001.aspx)而不是EXEC。 – kheld

回答

0

這應做到:

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

你試過了你的代碼嗎?它不會以這種方式工作。 NEXT VALUE的OVER子句僅適用於排序。它指定每行應用序列的順序。我需要按照我的問題所述的順序爲每套提供1個值。經過很多研究,我總結出這是不可能的,除了我詳細說明的方式。我希望有人能在我的發現中證明我錯了。起初,你會認爲NEXT VALUE會以這種方式工作,也似乎是一個邏輯功能。 – Jeff

+0

看看sp_sequence_get_range對你來說聽起來比動態DDL更好。無論哪種情況,此代碼在同時從多個連接運行時都會產生不正確的結果。 –

+0

你是否介意我問,爲什麼你在乎AKey每個等級組或每個記錄增加?你可以把它作爲TableA中的PK,並使用直接標識(或序列)? –

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的價值,因爲它是你的榜樣,你可以做羣ID + AKEY這裏。