2012-03-21 3 views
2

Можно ли написать триггер, который принимает внешние параметры?Как создать триггеры, которые принимают внешние параметры в SQL Server?

Основная причина этого - ограничить подключение к базе данных только с помощью ONE пользователя базы данных. Теперь я разрабатываю приложение базы данных и создаю триггеры для каждой отдельной таблицы для хранения истории.

При хранении данных истории, я хочу, чтобы сохранить Application Имя пользователя кто совершил Insert, Update или Delete. Я думал использовать User_Name(), но узнал, что он возвращает пользователя базы данных, NOT пользователь приложения.

Поэтому я ищу некоторые предложения по созданию триггеров с внешними параметрами, чтобы я мог передать идентификатор пользователя приложения этому триггеру. Думаю, я четко объяснил свои потребности. Заранее спасибо !

Редактировать
Внешний параметр должен быть что-то подобное параметров хранимой процедуры, где мы можем передать значение,

Edit2
Может быть мое описание не является достаточно ясным. Поэтому я даю вам пример.
Веб-приложение, которое я разрабатываю, относится к учетной записи. Таким образом, чтобы отслеживать изменения данных в необходимом. Например, персонал Счета может изменить информацию о зарплате и комиссии сотрудника. Если неправильная информация вводится/обновляется, общий финансовый результат будет иметь большое негативное влияние. Теперь в системе вход пользователя в систему с использованием пароля userid &, а затем выполните некоторые изменения в информации о сотрудниках. На этом этапе я хочу сохранить трек, который изменил информацию о сотрудниках, когда были сделаны изменения и значения до того, как изменение было выполнено, и значение после завершения изменения. Так что в будущем, если что-то пойдет не так, я могу узнать пользователя, который сделал ошибку с PROOF.
Не обязательно это должно быть сделано с помощью триггера, но любая другая альтернатива также приветствуется.

+0

Что такое идентификатор пользователя приложения? Это логин SQL, учетная запись Windows или что-то еще? Возвращает ли SYSTEM_USER то, что вы хотите или нет? – Pondlife

+0

Откуда у вас пользователь приложения? Почему вы не можете найти пользователя приложения внутри триггера? – adrianm

+0

Возможный дубликат [Передача переменной в триггер] (http://stackoverflow.com/questions/2646547/pass-a-variable-into-a-trigger) попробуйте использовать 'CONTEXT_INFO()', см. Ссылку для ответов используя это. –

ответ

5

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


При подключении к базе данных, каждое соединение получает свой собственный идентификатор процесса. Вы можете получить это через @@ spid.

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

У вас может быть 100 одновременных соединений с использованием одного и того же входа в базу данных, и каждый из них будет иметь собственное значение @@ spid.


Для того, чтобы быть полезным для вас, однако, вы должны подготовить все соединения. Каждый раз, когда соединение выполняется, ваше приложение должно писать в таблицу, чтобы записать, какое использование приложения использует этот @@ spid.

Может быть как-то просто, как ...

CREATE TABLE 
    map_spid_application_user (
    spid   BIGINT, 
    application VARCHAR(128), 
    user   VARCHAR(128), 
    PRIMARY KEY (spid) 
) 

Затем на каждом соединении, запустить что-то вроде этого (возможно, через хранимые процедуры) ...

DELETE map_spid_application_user WHERE spid = @@spid 

INSERT INTO map_spid_application_user SELECT @@spid, 'myApp', 'myUser' 


Затем в вашем триггере вы можете ссылаться/присоединяться к этой таблице, чтобы узнать, к кому относится @@ spid.


Вы также можете получить более умными, и использовать подобный подход, чтобы держать постоянную запись о том, что пользователь может быть подключен, а каким ИСП. Текущий пользователь для любого spid всегда будет с последним временем соединения datetime.


Вы можете сделать почти все, что вам нравится то. Поскольку вы создаете всю информацию и не полагаетесь на базу данных на , просто знайте ничего, кроме @@ spid.

+0

Я попробую это –

1

Храните имя пользователя в каждой таблице и передавайте его в качестве параметра во время изменения данных. Оттуда триггер может архивировать данные в другую таблицу (таблицы).

+0

«Сохраните имя пользователя в каждой таблице и передайте его как параметр во время изменения данных». Я немного смущен тем, что вы пытаетесь сказать. ( –

1

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

Пример таблицы:.

CREATE TABLE RAF1 
(
strona NUMBER, 
nazwa VARCHAR2(40) 
); 

Пример Trigger (триггер будет всегда, если вы поставите nazw = «же» Nazwa записи = 'Роланда `s, подключенного к этой таблице вы можете редактировать этот пример

create or replace TRIGGER sam 
BEFORE INSERT OR UPDATE OF nazwa 
ON RAF1 FOR EACH ROW WHEN (new.nazwa = 'same') 
BEGIN :new.nazwa := 'ronald'; END 
+1

Этот вопрос предназначен для SQL-Server, а не для Oracle. – MatBailie

0

Я сделал то, что вы описали. Я не могу сказать, что я был доволен результатом, потому что решение может быть довольно хрупким, когда происходит что-то странное, как общение. Это также просто неправильно, но попробуйте, если хотите.

  1. Со стороны приложения введите имя пользователя в свойство AppName ConnectionString.
  2. В триггере укажите функцию App_Name().

Опять же, это будет делать то, что вы просите, но я не рекомендую его. Лучше просто управлять аудиторской информацией как частью основного материала вставки/обновления от клиента или с помощью хранимых процедур.

Смежные вопросы