1

シナリオは次のとおりです。

テーブルRequest(RId)、テーブル、テーブルがService(SId)ありますMapping(MId)

まず、リクエストが Request テーブルに生成されます。次に、関連する n 個のサービスが作成されます。1 つのリクエストに対して 5 つのサービスがあるとします。現在、テーブル Request とテーブル Service の間の関係を維持するマッピング テーブルがあります。

マッピング テーブルの例:

MId | RId | SId
----------------
 1  |  1  |  2
 2  |  1  |  3  
 3  |  1  |  4
 4  |  2  |  5
 5  |  2  |  6
 6  |  3  |  8

今、私はこれを行う2つの方法があります:

1 番目のパス: DB の SP に 1 つのサービスを挿入し、挿入を行ってから、その ID を取得し、Mappingテーブルにエントリを作成します。5 つのサービスがある場合、バックエンドに 5 回アクセスする必要があります (サービスの挿入と単一 SP でのマッピング)(現在使用しているもの)。

2 番目のパス: すべてのサービス データを TableType として SP に送信し、DB に挿入して最後の 5 つのサービス ID を取得し、while ループを介してマッピング テーブルへのすべてのエントリを実行します。つまり、バックエンドに一度だけアクセスする必要がありますが、他の人が自分のリクエストに対してサービスを挿入した場合、間違った ID を取得し、マッピングを間違って行うことになります。

これを行うより良い方法はありますか?

4

2 に答える 2

3

この句を使用して、OUTPUT挿入された複数の行から ID を取得できます。ServiceName以下では、渡された値を一意に識別するのにと で十分であると想定してRequestNameいます。または値):

まず、テーブルをセットアップします。

create table Requests (RId int IDENTITY(1,1) not null primary key,RequestName varchar(10) not null)
create table Services (SId int IDENTITY(1,1) not null primary key,ServiceName varchar(10) not null)
create table Mappings (MId int IDENTITY(1,1) not null,RId int not null references Requests,SId int not null references Services)

ここで、ストアド プロシージャに渡されるTVPを宣言します (このスクリプトと次のスクリプトは、このシミュレーションで一緒に実行する必要があることに注意してください)。

declare @NewValues table (
    RequestName varchar(10) not null,
    ServiceName varchar(10) not null
)
insert into @NewValues (RequestName,ServiceName) values
('R1','S1'),
('R1','S2'),
('R1','S3'),
('R2','S4'),
('R2','S5'),
('R3','S6')

そして、SP 内には、次のようなコードがあります。

declare @TmpRIDs table (RequestName varchar(10) not null,RId int not null)
declare @TmpSIDs table (ServiceName varchar(10) not null,SId int not null)

;merge into Requests r using (select distinct RequestName from @NewValues) n on 1=0
when not matched then insert (RequestName) values (n.RequestName)
output n.RequestName,inserted.RId into @TmpRIDs;

;merge into Services s using (select distinct ServiceName from @NewValues) n on 1=0
when not matched then insert (ServiceName) values (n.ServiceName)
output n.ServiceName,inserted.SId into @TmpSIDs;

insert into Mappings (RId,SId)
select RId,SId
from @NewValues nv
    inner join
    @TmpRIds r
        on
            nv.RequestName = r.RequestName 
    inner join
    @TmpSIDs s
        on
            nv.ServiceName = s.ServiceName;

結果を確認するには:

select * from Mappings

生成:

MId         RId         SId
----------- ----------- -----------
1           1           1
2           1           2
3           1           3
4           2           4
5           2           5
6           3           6

これは、あなたの質問にあるものと似ています。

コードのトリッキーな部分は、テーブル (新しく生成された値を含む) と行のソースとして機能しているテーブルの両方から列をキャプチャできるようにするために、ステートメントを (誤って) 使用していることです。ステートメントの句は、疑似テーブルへの参照のみを許可するため、ここでは使用できません。MERGEinsertedIDENTITYOUTPUTINSERTinserted

于 2013-04-12T07:05:44.523 に答える