Một mẫu khá phổ biến trong ứng dụng cơ sở dữ liệu mà tôi làm việc là cần tạo một thủ tục được lưu trữ cho một báo cáo hoặc tiện ích có "chế độ xem trước". Khi một thủ tục như vậy thực hiện cập nhật, tham số này chỉ ra rằng kết quả của hành động sẽ được trả về, nhưng thủ tục không thực sự thực hiện các cập nhật cho cơ sở dữ liệu.
Một cách để thực hiện điều này là chỉ cần viết một if
câu lệnh cho tham số và có hai khối mã hoàn chỉnh; một trong số đó cập nhật và trả về dữ liệu và cái còn lại chỉ trả về dữ liệu. Nhưng điều này là không mong muốn vì sự trùng lặp mã và mức độ tin cậy tương đối thấp rằng dữ liệu xem trước thực sự là một sự phản ánh chính xác về những gì sẽ xảy ra với một bản cập nhật.
Ví dụ sau đây cố gắng tận dụng các điểm lưu trữ và biến số giao dịch (không bị ảnh hưởng bởi các giao dịch, ngược lại với các bảng tạm thời) để chỉ sử dụng một khối mã duy nhất cho chế độ xem trước làm chế độ cập nhật trực tiếp.
Lưu ý: Rollback giao dịch không phải là một tùy chọn vì lệnh gọi thủ tục này có thể được lồng trong một giao dịch. Điều này đã được thử nghiệm trên 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
Tôi đang tìm kiếm phản hồi về mã và mẫu thiết kế này và / hoặc nếu các giải pháp khác cho cùng một vấn đề tồn tại ở các định dạng khác nhau.