รูปแบบที่พบบ่อยพอสมควรในแอปพลิเคชันฐานข้อมูลที่ฉันทำงานด้วยคือต้องสร้างขั้นตอนการจัดเก็บสำหรับรายงานหรือยูทิลิตี้ที่มี "โหมดตัวอย่าง" เมื่อโพรซีเดอร์ดังกล่าวทำการอัพเดตพารามิเตอร์นี้บ่งชี้ว่าผลลัพธ์ของแอ็คชันควรถูกส่งคืน แต่โพรซีเดอร์ไม่ควรทำการอัพเดตกับฐานข้อมูล
วิธีหนึ่งในการทำสิ่งนี้ให้สำเร็จคือการเขียนif
คำสั่งสำหรับพารามิเตอร์และมีโค้ดบล็อกที่สมบูรณ์สองบล็อก หนึ่งในนั้นจะปรับปรุงและส่งคืนข้อมูลและอื่น ๆ เพียงแค่ส่งคืนข้อมูล แต่สิ่งนี้ไม่เป็นที่พึงปรารถนาเนื่องจากการทำสำเนารหัสและความเชื่อมั่นค่อนข้างต่ำว่าข้อมูลตัวอย่างเป็นภาพสะท้อนที่ถูกต้องแม่นยำว่าจะเกิดอะไรขึ้นกับการอัปเดต
ตัวอย่างต่อไปนี้พยายามใช้ประโยชน์จากจุดบันทึกและตัวแปรของการทำธุรกรรม (ซึ่งไม่ได้รับผลกระทบจากธุรกรรมตรงกันข้ามกับตาราง temp ซึ่งเป็น) เพื่อใช้รหัสบล็อกเดียวสำหรับโหมดแสดงตัวอย่างเป็นโหมดการอัปเดตสด
หมายเหตุ: การย้อนกลับของธุรกรรมไม่ใช่ตัวเลือกเนื่องจากการเรียกขั้นตอนนี้อาจซ้อนอยู่ในธุรกรรม นี่คือการทดสอบใน 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
ฉันกำลังมองหาข้อเสนอแนะเกี่ยวกับรหัสและรูปแบบการออกแบบนี้และ / หรือหากวิธีแก้ไขปัญหาอื่น ๆ มีอยู่ในรูปแบบที่แตกต่างกัน