Существует ли режим / профиль / разрешение, которое автоматически откатывает все запросы, отправленные пользователем? - PullRequest
0 голосов
/ 14 сентября 2018

На работе у нас есть производственные базы данных, на которые разработчики имеют разрешение на чтение. Когда разработчикам необходимо что-то исправить в базе данных, они должны проверить свои сценарии в копии производственных баз данных, а затем попросить группу администраторов баз данных выполнить их в работе.

Иногда, однако, данные, которые необходимо исправить, отсутствуют в тестовых базах данных. Затем разработчики запрашивают новую копию производственных баз данных, и это может занять много времени.

Конечно, мы могли бы предоставить им разрешение на обновление и попросить их использовать BEGIN TRANSACTION / ROLLBACK, но это слишком рискованно. Никто не хочет этого, даже разработчики.

Мой вопрос : возможно ли создать профиль на SQL Server или предоставить ему специальное разрешение, которое позволило бы выполнять команды обновления и удаления, но всегда , независимо от того, что разработчик написал: откат после GO или после последней команды, введенной в сеансе?

Это было бы очень полезно для тестирования сценариев перед отправкой их в производство.

1 Ответ

0 голосов
/ 21 сентября 2018

Вы можете создать 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
...