SQLServerでSequenceを実現する効率的な方法
1715 ワード
ORACLEでSequenceを使い慣れた親たちが、SqlServerでSequenceを実現しようとすると、既存のSequenceオブジェクトがCreateできないことに気づきます.どうすればいいですか?もちろん、この小さな問題は私たちのプログラマーを倒すことはできません.「max+1ですね」と、このような方法を言う人がいます.はい、この方法は実現も簡単です.もちろん、最もSqlの方法はidentity列を採用し、自増の方法で増加すればokだと言うかもしれません.しかし、このような列は、「YYYYYMMDD」+Sequence値(例えば、2008,072400001)のフォーマットを実現するにはだめです.やはりおとなしく実用的なストレージプロセスでSequence値を取得しましょう.使い勝手もいいです.
ネット上でよく見られるストレージ・プロシージャは、現在のライブラリで使用されているすべてのSequenceに対してテーブルを作成します.たとえば、「AllSequence」には、4つのフィールド【名前、開始値、付加価値、現在値】が含まれています.Sequenceを作成すると、レコードが作成され、Sequenceを取得すると、対応するローの現在値から付加価値で増加します.
コンカレントリクエストがそれほど高くないシステムでは、このプロセスは問題ありません.しかし、コンカレントリクエストがあるレベルになると、このプロセスはしばしば問題に直面します.
1秒あたり数千回の要求など、スループットの高いアクセス要求に適した改善方法を以下に示します.
先ほどお話しした「200807400056」というフォーマットを取得するには、次のようにします.
select Convert(char(8),Getdate(),112) + right(‘00000’+CAST(@NewSeqVal AS varchar(5)),5) as mySeq
ただし、プロシージャを格納しないselectの文で直接使用することはできません.
ネット上でよく見られるストレージ・プロシージャは、現在のライブラリで使用されているすべてのSequenceに対してテーブルを作成します.たとえば、「AllSequence」には、4つのフィールド【名前、開始値、付加価値、現在値】が含まれています.Sequenceを作成すると、レコードが作成され、Sequenceを取得すると、対応するローの現在値から付加価値で増加します.
コンカレントリクエストがそれほど高くないシステムでは、このプロセスは問題ありません.しかし、コンカレントリクエストがあるレベルになると、このプロセスはしばしば問題に直面します.
1秒あたり数千回の要求など、スループットの高いアクセス要求に適した改善方法を以下に示します.
-- T_0101001 Sequence
-- SeqT_0101001
create table SeqT_0101001(
-- ID
SeqID int identity(1,1) primary key,
-- Sequence
SeqVal varchar(1)
)
-- SeqT_0101001 Sequence
create procedure P_GetNewSeqVal_SeqT_0101001
as
begin
-- Sequence
declare @NewSeqValue int
-- 、
set NOCOUNT ON
-- SeqT_0101001
insert into SeqT_0101001 (SeqVal) values ('a')
-- Sequence SeqT_0101001
set @NewSeqValue = scope_identity()
-- SeqT_0101001 ( )
delete from SeqT_0101001 WITH (READPAST)
-- Sequence
return @NewSeqValue
end
-- Sequence
Declare @NewSeqVal int
Exec @NewSeqVal = P_GetNewSeqVal_SeqT_0101001
Print @NewSeqVal
先ほどお話しした「200807400056」というフォーマットを取得するには、次のようにします.
select Convert(char(8),Getdate(),112) + right(‘00000’+CAST(@NewSeqVal AS varchar(5)),5) as mySeq
ただし、プロシージャを格納しないselectの文で直接使用することはできません.