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秒あたり数千回の要求など、スループットの高いアクセス要求に適した改善方法を以下に示します.
--     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の文で直接使用することはできません.