@Davidの「進行状況」テーブルにデータを入れるという提案に似ていますが、クリーンアップや同時実行性、プロセス分離の問題を混乱させる必要はありません。
Guid
アプリのコード内で新規を作成し、それをパラメーターとしてストアード・プロシージャーに渡します。このGUIDは数回使用されるため、変数に格納します。
- ストアドプロシージャで、テーブル名の一部としてそのGUIDを使用して、グローバル一時テーブルを作成します
CREATE TABLE ##MyProcess_{GuidFromApp};
。テーブルには、必要なデータ型の列を含めることができます。
データがある場合は、そのグローバル一時テーブルに挿入します。
アプリのコードでは、データを読み出そうと始めるが、ラップSELECT
にIF EXISTS
テーブルがまだ作成されていない場合、それは失敗しないように。
IF (OBJECT_ID('tempdb..[##MyProcess_{0}]')
IS NOT NULL)
BEGIN
SELECT * FROM [##MyProcess_{0}];
END;
を使用すると、Guid変数の値にString.Format()
置き換えることができ{0}
ます。ifをテストしReader.HasRows
、trueの場合は結果を読み取り、それ以外のThread.Sleep()
場合は何でも呼び出して再度ポーリングします。
利点:
- アプリのコードだけが特定のGuid値を知っているため、このテーブルは他のプロセスから分離されているため、他のプロセスについて心配する必要はありません。別のプロセスには、独自のプライベートグローバル一時テーブルがあります。
- テーブルなので、すべてが強く型付けされています。
- これは一時テーブルなので、ストアドプロシージャを実行するセッションが終了すると、テーブルは自動的にクリーンアップされます。
- これはグローバル一時テーブル
なので、
- 永続テーブルのように、他のセッションからアクセスできます
- それが作成されたサブプロセス(つまり
EXEC
/ sp_executesql
呼び出し)の終了後も存続します。
私はこれをテストしましたが、期待どおりに動作します。次のコード例を使用して、自分で試してみることができます。
1つのクエリタブで次を実行し、ブロックコメントの3行を強調表示して実行します。
CREATE
--ALTER
PROCEDURE #GetSomeInfoBackQuickly
(
@MessageTableName NVARCHAR(50) -- might not always be a GUID
)
AS
SET NOCOUNT ON;
DECLARE @SQL NVARCHAR(MAX) = N'CREATE TABLE [##MyProcess_' + @MessageTableName
+ N'] (Message1 NVARCHAR(50), Message2 NVARCHAR(50), SomeNumber INT);';
-- Do some calculations
EXEC (@SQL);
SET @SQL = N'INSERT INTO [##MyProcess_' + @MessageTableName
+ N'] (Message1, Message2, SomeNumber) VALUES (@Msg1, @Msg2, @SomeNum);';
DECLARE @SomeNumber INT = CRYPT_GEN_RANDOM(2);
EXEC sp_executesql
@SQL,
N'@Msg1 NVARCHAR(50), @Msg2 NVARCHAR(50), @SomeNum INT',
@Msg1 = N'wow',
@Msg2 = N'yadda yadda yadda',
@SomeNum = @SomeNumber;
WAITFOR DELAY '00:00:10.000';
SET @SomeNumber = CRYPT_GEN_RANDOM(3);
EXEC sp_executesql
@SQL,
N'@Msg1 NVARCHAR(50), @Msg2 NVARCHAR(50), @SomeNum INT',
@Msg1 = N'wow',
@Msg2 = N'yadda yadda yadda',
@SomeNum = @SomeNumber;
WAITFOR DELAY '00:00:10.000';
GO
/*
DECLARE @TempTableID NVARCHAR(50) = NEWID();
RAISERROR('%s', 10, 1, @TempTableID) WITH NOWAIT;
EXEC #GetSomeInfoBackQuickly @TempTableID;
*/
[メッセージ]タブに移動し、印刷されたGUIDをコピーします。次に、別のクエリタブを開いて次を実行し、他のセッションの[メッセージ]タブからコピーしたGUIDを1行目の変数の初期化に配置します。
DECLARE @TempTableID NVARCHAR(50) = N'GUID-from-other-session';
EXEC (N'SELECT * FROM [##MyProcess_' + @TempTableID + N']');
叩き続けるF5。最初の10秒間は1つのエントリが表示され、次の10秒間は2つのエントリが表示されます。