INSERT хранимых процедур T-SQL гарантированно перед SELECT? - PullRequest
2 голосов
/ 17 июня 2011

У меня есть хранимая процедура, которая извлекает конфиденциальную информацию из базы данных SQL Server 2008.Я хотел бы изменить процедуру так, чтобы при каждом вызове она записывала информацию о том, кто вызвал ее, в отдельной таблице.

Я думал, что сработает что-то вроде следующего:

declare @account varchar(255);
set @account = (SELECT SYSTEM_USER);

INSERT into AUDIT_LOG(ACCOUNT, TSTAMP)
VALUES(@account, getdate())
;

--Now fetch data
SELECT x,y,z from sensitive_info;

Моя проблема в том, что клиентское приложение может выполнить вызов этой хранимой процедуры и получить конфиденциальную информацию, но не фиксирует соединение, и INSERT никогда не происходит!

Есть ли какой-то способзаставить вставку произойти до SELECT?

Я использую SQL Server 2008.

Спасибо, Карл

Ответы [ 4 ]

2 голосов
/ 17 июня 2011

COMMIT только если транзакция была начата.

Таким образом, вы можете сначала проверить открытую транзакцию и запретить чтение. Это гарантирует, что ни одна транзакция не будет открыта для отката. Я использовал XACT_STATE () здесь

Использование SET XACT_ABORT ON и TRY / CATCH также будет означать, что INSERT для ведения журнала должен произойти также до того, как произойдет чтение. Любые ошибки на всех на INSERT перейдут в блок CATCH. Таким образом, нет чтения, и ошибка регистрации сама по себе также не может быть зарегистрирована.

Итак: это ваша гарантия «только для чтения, если зарегистрирован»

Наличие явной транзакции не помогает: вставка в любом случае является атомарным действием. И если вызываемый открывает транзакцию, запись в журнале может быть откатана

CREATE PROC getSecretStuff
AS
SET NOCOUNT, XACT_ABORT ON;

BEGIN TRY
    IF XACT_STATE() <> 0
       RAISERRROR ('Call not allowed in an active transaction', 16, 1)

    INSERT into AUDIT_LOG(ACCOUNT, TSTAMP)
    VALUES(SYSTEM_USER, getdate());

    --Now fetch data
    SELECT x,y,z from sensitive_info;

END TRY
BEGIN CATCH
    --     error handling etc
END CATCH
GO
1 голос
/ 17 июня 2011

Почему бы не использовать встроенную функцию аудита ?

0 голосов
/ 17 июня 2011

Когда вы вставляете запись в таблицу, вы должны всегда получать SCOPE_IDENTITY () из вставленного значения ast. Перед выполнением SELECT x, y, z из Sens_info; Вы можете проверить, если SCOPE_IDENTITY ()> 0, тогда выполнить только инструкцию SELECT.

0 голосов
/ 17 июня 2011

Вы пытались использовать явные транзакции и делать выбор после оператора фиксации?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...