私が使用しているデータベースアプリケーションのかなり一般的なパターンは、「プレビューモード」を持つレポートまたはユーティリティのストアドプロシージャを作成する必要があることです。そのようなプロシージャが更新を行う場合、このパラメータはアクションの結果が返されるべきであることを示しますが、プロシージャは実際にデータベースの更新を実行するべきではありません。
これを実現する1つの方法if
は、パラメーターのステートメントを記述するだけで、2つの完全なコードブロックを作成することです。1つは更新を実行してデータを返し、もう1つはデータを返すだけです。しかし、これは、コードの重複と、プレビューデータが実際に更新で発生することを正確に反映しているという比較的低い信頼度のため、望ましくありません。
次の例では、トランザクションセーブポイントと変数(一時テーブルとは対照的に、トランザクションの影響を受けない)を活用して、ライブ更新モードとしてプレビューモードのコードの単一ブロックのみを使用しようとします。
注:トランザクションのロールバックは、このプロシージャコール自体がトランザクションにネストされている可能性があるため、オプションではありません。これはSQL Server 2012でテストされています。
CREATE TABLE dbo.user_table (a int);
GO
CREATE PROCEDURE [dbo].[PREVIEW_EXAMPLE] (
@preview char(1) = 'Y'
) AS
CREATE TABLE #dataset_to_return (a int);
BEGIN TRANSACTION; -- preview mode required infrastructure
DECLARE @output_to_return TABLE (a int);
SAVE TRANSACTION savepoint;
-- do stuff here
INSERT INTO dbo.user_table (a)
OUTPUT inserted.a INTO @output_to_return (a)
VALUES (42);
-- catch preview mode
IF @preview = 'Y'
ROLLBACK TRANSACTION savepoint;
-- save output to temp table if used for return data
INSERT INTO #dataset_to_return (a)
SELECT a FROM @output_to_return;
COMMIT TRANSACTION;
SELECT a AS proc_return_data FROM #dataset_to_return;
RETURN 0;
GO
-- Examples
EXEC dbo.PREVIEW_EXAMPLE @preview = 'Y';
SELECT a AS user_table_after_preview_mode FROM user_table;
EXEC dbo.PREVIEW_EXAMPLE @preview = 'N';
SELECT a AS user_table_after_live_mode FROM user_table;
-- Cleanup
DROP TABLE dbo.user_table;
DROP PROCEDURE dbo.PREVIEW_EXAMPLE;
GO
このコードとデザインパターンに関するフィードバック、および/または同じ問題に対する別の解決策が異なる形式で存在するかどうかを探しています。