내가 작업하는 데이터베이스 응용 프로그램에서 상당히 일반적인 패턴은 "미리보기 모드"가있는 보고서 또는 유틸리티에 대해 저장 프로 시저를 만들어야한다는 것입니다. 이러한 프로 시저가 업데이트를 수행 할 때이 매개 변수는 조치 결과가 리턴되어야하지만 실제로 프로시 저는 데이터베이스에 대한 업데이트를 수행하지 않아야 함을 나타냅니다.
이를 수행하는 한 가지 방법 if
은 매개 변수에 대한 명령문을 작성하고 두 개의 완전한 코드 블록을 갖는 것입니다. 하나는 데이터를 업데이트하고 반환하고 다른 하나는 데이터를 반환합니다. 그러나 이것은 코드 복제와 미리보기 데이터가 실제로 업데이트로 발생하는 상황을 정확하게 반영한다는 비교적 낮은 신뢰도 때문에 바람직하지 않습니다.
다음 예제는 트랜잭션 세이브 포인트 및 변수 (임시 테이블과 달리 트랜잭션의 영향을받지 않음)를 사용하여 미리보기 모드에 대해 단일 코드 블록 만 라이브 업데이트 모드로 사용하려고합니다.
참고 : 이 프로 시저 호출 자체가 트랜잭션에 중첩 될 수 있으므로 트랜잭션 롤백 은 옵션이 아닙니다. 이것은 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
이 코드 및 디자인 패턴에 대한 피드백을 찾고 있거나 동일한 문제에 대한 다른 솔루션이 다른 형식으로 존재하는지 여부를 찾고 있습니다.