Вы можете создать sproc и предоставить EXEC доступ к разработчикам только для этого sproc, РЕШЕНИЕ № 1 - SPROCS .Это, пожалуй, самое элегантное решение, поскольку вы хотите, чтобы у них был простой способ выполнения запросов, а также чтобы они хотели контролировать свои привилегии в производственной среде.Пример выполнения команды: EXEC [dbo].[usp_rollback_query] 'master', 'INSERT INTO table1 SELECT * FROM table2
РЕШЕНИЕ № 1
USE [DATABASENAME]
GO
ALTER PROC dbo.usp_rollback_query
(
@db VARCHAR(128),
@query NVARCHAR(max)
)
AS
BEGIN
DECLARE @main_query NVARCHAR(max) = 'USE [' + @db + ']
' + @query;
BEGIN TRAN
EXEC sp_executesql @main_query;
ROLLBACK TRAN
END
Если вы можете позволить себе создавать и удалять снимки каждый раз, РЕШЕНИЕ № 2 - DB SNAPSHOTS - лучший способ сделать это.Это очень быстро, только два недостатка в том, что вам нужно выгнать людей из БД, прежде чем вы сможете восстановить, и он восстановит все изменения, сделанные с момента создания снимка.
РЕШЕНИЕ № 2
-- CREATE SNAPSHOT
CREATE DATABASE [DATABASENAME_SS1]
ON
(
NAME = DATABASENAME,
FILENAME = 'your\path\DATABASENAME_SS1.ss'
) AS SNAPSHOT OF [DATABASENAME];
GO
-- let devs run whatever they want
-- CLOSE CONNECTIONS
USE [master];
GO
ALTER DATABASE [DATABASENAME]
SET SINGLE_USER
WITH ROLLBACK IMMEDIATE;
GO
-- RETORE DB
RESTORE DATABASE [DATABASENAME]
FROM DATABASE_SNAPSHOT = 'DATABASENAME_SS1';
GO
-- CLEANUP SNAPSHOT COPY
DROP DATABASE [DATABASENAME_SS1];
Я не думаю, что ROLLBACK для каждого запроса - это хорошая идея или хороший дизайн, но если вам нужно идти по этому пути,вам нужно будет использовать триггеры.Ограничением для триггеров является то, что триггер уровня DATABASE или SERVER может быть только для DDL, а не для DML.Создание триггеров для каждого объекта TABLE, который, по вашему мнению, изменяется, выполнимо, однако недостатком здесь является то, что вам нужно знать, какие таблицы изменяются, и даже тогда это довольно грязно.В любом случае, пожалуйста, посмотрите РЕШЕНИЕ № 3 - ТАБЛИЦА ТРИГГЕРОВ ниже.Чтобы сделать это лучше, вы можете создать роль и проверить, является ли пользователь этой ролью, а затем выполнить откат.
РЕШЕНИЕ № 3
USE DATABASENAME
GO
ALTER TRIGGER dbo.tr_rollback_devs
ON dbo.table_name
AFTER INSERT, DELETE, UPDATE
AS
BEGIN
SET NOCOUNT ON;
IF SYSTEM_USER IN ('dev1', 'dev2')
ROLLBACK
END
GO