パーシスタンス レイヤーを Oracle から別のデータベースに移植するためのさまざまなオプションを検討しており、その中の 1 つが MS SQL です。ただし、コード全体で Oracle シーケンスを使用しているため、移動が頭痛の種になるようです。@identity については理解していますが、それは永続化コードの大規模なオーバーホールになります。
SQL Server でシーケンスを処理できる関数を作成することは可能ですか?
パーシスタンス レイヤーを Oracle から別のデータベースに移植するためのさまざまなオプションを検討しており、その中の 1 つが MS SQL です。ただし、コード全体で Oracle シーケンスを使用しているため、移動が頭痛の種になるようです。@identity については理解していますが、それは永続化コードの大規模なオーバーホールになります。
SQL Server でシーケンスを処理できる関数を作成することは可能ですか?
私はプロジェクトで昨年これを行いました。基本的に、シーケンスの名前、現在の値、および増分量を含むテーブルを作成しました。
次に、4 つの procs を作成しました。
しかし、理解できないかもしれない制限があります。関数は副作用を持つことができません。したがって、GetCurrentSequence(...) の関数を作成できますが、GetNextSequence(...) は proc である必要があります。これは、おそらく現在のシーケンス値をインクリメントする必要があるためです。ただし、proc の場合は、insert ステートメントで直接使用することはできません。
だから代わりに
insert into mytable(id, ....) values( GetNextSequence('MySequence'), ....);
代わりに、2 行に分割する必要があります。
declare @newID int;
exec @newID = GetNextSequence 'MySequence';
insert into mytable(id, ....) values(@newID, ....);
また、SQL Serverには、次のようなことができるメカニズムがありません
MySequence.Current
また
MySequence.Next
うまくいけば、誰かが私が上記の制限で間違っていると言ってくれることを願っていますが、私はそれらが正確であると確信しています.
幸運を。
これは、Oracle でのシーケンスの現在の使用状況によって異なります。通常、シーケンスは Insert トリガーで読み込まれます。
あなたの質問から、データベースに挿入する前にシーケンスを生成するのは永続層であると思います(新しいpkを含む)
MSSQL では、SQL ステートメントを ';' で組み合わせることができるため、新しく作成されたレコードの ID 列を取得するには、INSERT INTO ... を使用します。スコープ_IDENTITY()を選択
したがって、レコードを挿入するコマンドは、ID 列の値を含む 1 つの行と 1 つの列を含むレコードセットを返します。
もちろん、このアプローチを変えて、次のようなシーケンス テーブル (Oracle のデュアル テーブルに似ています) を作成することもできます。
INSERT INTO SequenceTable (dummy) VALUES ('X');
SELECT @ID = SCOPE_IDENTITY();
INSERT INTO RealTable (ID, datacolumns) VALUES (@ID, @data1, @data2, ...)
コードがたくさんある場合は、とにかくコードの大規模なオーバーホールを行いたいと思うでしょう。Oracleでうまく機能するものが、MSSQLで常にうまく機能するとは限りません。たとえば、カーソルがたくさんある場合、それらを1行ずつMSSQLに変換することはできますが、良好なパフォーマンスは得られません。
要するに、これは簡単な作業ではありません。