3

この質問が少し漠然としている場合は、事前にお詫び申し上げます。構文の問題ではなく、概念的な問題であると確信しています。

私はMSSQL(SQL Server 2008)を使用しており、ユーザー定義テーブルタイプのテーブル値パラメーターを取るストアドプロシージャがあります(DataTableを渡す.NETコードによって呼び出されています)。

私が直面している問題は次のとおりです。
そのテーブル変数のデータを操作する必要がありますが、変数自体は READONLY です (そして、私が理解していることから、ストアド プロシージャに渡すために必要です。ユーザー定義のテーブル タイプ)。

宛先テーブルへの最終的な挿入を行う前@TVPに、テーブルからすべてを選択して #temp を操作するという明白な解決策を検討しました。#tempただし、複数のストアド プロシージャを呼び出してデータを操作できるようにしたいと考えています。これは、呼び出し元と呼び出し先の間でテーブル変数をやり取りすることを意味します。実行する必要があるデータ操作の量は膨大であるため、複数のストアド プロシージャに分割しようとしています。私が知る限り、TVP は READONLY として装飾する必要があり、#tempテーブルをパラメータとしてストアド プロシージャに渡すことはできないため、これは不可能です。グローバルの使用を検討しました##tempただし、このプロシージャは異なるデータ セットで同時に複数回呼び出すことができます (一時的な物理テーブルに選択しない理由でもあります)。

概念的に、ここに欠けているものはありますか? これを達成するための最良の方法は何ですか?私はそれを単一の巨大なストアド プロシージャにしたいと思っていますが、より保守しやすくするためにはしたくありません。

要点をまとめると:

私は P_CALLER、P_CALLEE_1、および P_CALLEE_2 を持っています (明らかに本名ではありません)。

  1. P_CALLER は @SomeTable を TVP として受け取ります。

  2. P_CALLER は、@SomeTable を P_CALLEE_1 に渡してデータを操作する必要があります。その後、修正された結果を P_CALLER に戻します。

  3. P_CALLER は同じことを行い、今度は P_CALLEE_2 を呼び出します。P_CALLEE_2 もそれを返します。

  4. P_CALLER は、DestinationTable への最終的な挿入を行います。

答えを見つけるためにグーグルを試しましたが、見つけた結果のどれも状況に完全に一致していないようです. アドバイスをいただければ幸いです。

4

1 に答える 1

1

親プロシージャで一時テーブルを作成し、子プロシージャ内から操作できます。

これは大雑把な例です。もちろん、本番環境では、防御的なプログラミング/トランザクション処理などでこれを強化します.

create type CustomTable as table (Id int primary key, Name varchar(10));
go

create procedure dbo.Worker1
as
begin
    delete from #work where Id > 5;
end
go

create procedure dbo.Worker2
as
begin
    insert into #work
        select -1, 'New One';
end
go

create procedure dbo.Driver (@input CustomTable readonly)
as
begin

    -- #work is created by dbo.Driver but visible to all child procs
    -- its also scoped to this instance of Driver
    select * into #work from @input; 

    -- do complicated work
    exec dbo.Worker1;
    exec dbo.Worker2;

    --return the final set (your insert into DestinationTable)
    select 'FINAL', * from #work;

end
return;

--usage

declare @table CustomTable;
insert into @table  
    values(1, 'One'),(2, 'Two'), (6, 'Six');

exec dbo.Driver @table;

戻り値:

      Id          Name
----- ----------- ----------
FINAL -1          New One
FINAL 1           One
FINAL 2           Two
于 2013-08-21T02:39:07.073 に答える