Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Триггера  [new]
ange
Member

Откуда:
Сообщений: 181
Доброе утро!
У меня на таблице висит триггер на все сразу (и обновление и удаление и вставку) для осуществления внутреннего аудита. Теперь хочу создать еще один триггер только на удаление - для удаления взаимосвязанных строк в других таблицах. Это грамотно? Или лучше первый триггер разбить на три и в тот, который получится для удаления довать текст второго триггера. И если можно не разбивать на три триггера, то какой за каким сработает?
2 фев 05, 09:34    [1292814]     Ответить | Цитировать Сообщить модератору
 Re: Триггера  [new]
tpg
Member

Откуда: Novosibirsk
Сообщений: 23902
ange
Доброе утро!
У меня на таблице висит триггер на все сразу (и обновление и удаление и вставку) для осуществления внутреннего аудита. Теперь хочу создать еще один триггер только на удаление - для удаления взаимосвязанных строк в других таблицах. Это грамотно? Или лучше первый триггер разбить на три и в тот, который получится для удаления довать текст второго триггера.

Да, лучше разбить. По крайней мере лишних танцев по определению операции удастся избежать.
ange
И если можно не разбивать на три триггера, то какой за каким сработает?
Триггер будет срабатывать на соответствующую операцию, а в какой они последовательности идут - это уже зависит от вашей логики.
2 фев 05, 09:40    [1292842]     Ответить | Цитировать Сообщить модератору
 Re: Триггера  [new]
ange
Member

Откуда:
Сообщений: 181
спасибо
еще вопрос - в триггере на update нужно отработать только для строк, в которых изменилось поле IsBoss

пытаюсь взять эти строки через

(select * from inserted inner join deleted on inserted.c_id=deleted.c_id where inserted.IsBoss<>deleted.IsBoss) t2

c_Id - полt уникальное, на инкременте
ругается "the cjlumn c_id was spesified multiple times for t2"
2 фев 05, 10:02    [1292952]     Ответить | Цитировать Сообщить модератору
 Re: Триггера  [new]
tpg
Member

Откуда: Novosibirsk
Сообщений: 23902
А весь скрипт запроса можно увидеть?
2 фев 05, 10:09    [1293003]     Ответить | Цитировать Сообщить модератору
 Re: Триггера  [new]
ange
Member

Откуда:
Сообщений: 181
аааа, я все поняла
балда!!!

написала select * а туда войдет с_id и из inserted и из deleted вот и ругается
inserted.* спасает
2 фев 05, 10:11    [1293010]     Ответить | Цитировать Сообщить модератору
 Re: Триггера  [new]
ange
Member

Откуда:
Сообщений: 181
Все, совсем запуталась
Рассказываю по порядку
есть таблица
CREATE TABLE T_UsersAccessToClient(
C_id bigint IDENTTY(1,1) NOT NULL,
User_Login nvarchar(50) NOT NULL,
Area_ID bigint NOT NULL,
IsCurator smallint NOT NULL
)

в ней для каждого пользователя, имеющего ограниченный доступ к данным указан список разрешенных ему регионов (Area_ID). Кроме того, пользователь может курировать этот регион, в этом случае поле IsCurator=1, иначе =-1
Курировать тот или иной район может только 1 человек -> при попытке установить значение 1 для поля IsCurator для одного пользователя, для других пользователей, у которых стоит IsCurator=1 для того же региона проставляем (-1 ) Есть раойны которые могут никем не курироваться

CREATE PROCEDURE AreaToCurator
@Login nvarchar(50),
@IsCurator as smallint,
@State_Name nvarchar(42),
@Area_Name nvarchar(68)
AS

Set nocount on

BEGIN

UPDATE t1 set IsCurator= case when @IsCurator=-1 Then -1 else case when (t1.UserLogin=@Login) Then @IsCurator else @IsCurator-2*@IsCurator end end
from T_UsersAccessToClient t1 join d_area t2 on (t1.area_id=t2.area_id) and (t2.area_name=@area_name) join d_state t3 on (t3.state_id=t2.state_id) and (t3.state_name=@state_name)

END

set nocount off

GO


есть таблица T_Enterprise (обрежем ее - скажем вот такая)
CREATE TABLE T_Enterprise(
Enterprise_id bigint IDENTTY(1,1) NOT NULL,
Legal_Name nvarchar(50) NOT NULL,
Area_ID bigint NOT NULL,
Curator nvarchar(150)
)

Решила отдельно запихнуть в нее поле куратор, чтобы каждый раз при селекте не джойнить с таблицей T_UsersAccessToClient (чтобы получить логин куратора) и таблицей T_Users (чтобы получмть ФИО куратора) Тем более что кураторство меняется очень редко, а селекты по T_Enterprise выполняются часто.
На таблицу T_Enterprise повесила 3 триггера - для внутреннего аудита.

Теперь стоит задача. При изменении значения IsCurator в T_UsersAccessToClient нужно изменять значение Curator в T_Enterprise
Пытаюсь повесить два триггера ( на добавление строк не вешаю, по умолчанию когда даю пользователю доступ, куратор проставляется в -1, чтобы установить кураторство нужно поставить ручками в формочке галочку)

1) на удаление строк - в этом случае в T-enterprise поле curator устанавливаю в '' там где IsCurator в deleted=1 - все в порядке
2) на обновление - вот здесь запуталась
написала вот так

CREATE Trigger EnterpriseCurator on T_UsersAccessToClient for update
as
set nocount on
begin
update t1 set Curator='' from t_enterprise t1 join 
(select inserted.* from inserted i inner join deleted d on i.c_id=d.c_id where i.IsCurator<>d.IsCurator and i.IsCurator=-1) t2 on (t1.area_id=t2.area_id)

update t1 set Curator=t3.User_SurName + ' ' + t3.User_FirstName + ' ' + t3.User_PatronymicName
from t_enterprise t1 join 
(select inserted.* from inserted i inner join deleted d on i.c_id=d.c_id where i.IsCurator<>d.IsCurator and i.IsCurator=1) t2 on (t1.area_id=t2.area_id) join T_Users t3 on (t2.user_login=t3.user_login)

end

set nocount of

так все работает нормально и при попытке поставить галочку польз-лю и при попытке убрать галочку с польз-ля и при попытке одновременно одному поставить, другому убрать, но в последнем случае в таблице T_enterprise выполняются лишние действия - вначале куратор проставляется в '' (ведь вначале убираем кураторство предыдущего), а потом проставляется новый. как только не крутила, чтобы выделить в триггере те строки, в которых идет замена одного куратора на другого и напрямую менять на новое значение, но ничего что-то не выходит
2 фев 05, 11:41    [1293461]     Ответить | Цитировать Сообщить модератору
 Re: Триггера  [new]
Smirnov Anton
Member

Откуда: Н.Новгород
Сообщений: 3220
CREATE Trigger EnterpriseCurator on T_UsersAccessToClient for update
as
set nocount on
begin
update t1 set Curator= case i.IsCurator
                                  when -1 then ''
                                  when 1 then t3.User_SurName + ' ' + t3.User_FirstName + ' ' + t3.User_PatronymicName
                                end 
from t_enterprise t1 join 
(select inserted.* from inserted i inner join deleted d on i.c_id=d.c_id where i.IsCurator<>d.IsCurator) t2 on (t1.area_id=t2.area_id)
join T_Users t3 on (t2.user_login=t3.user_login)
set nocount off
:-)
только это, наверное, не поможет, тк вы на сервер посылаете 2 запроса
1)снять кураторство с первого
2)поставить кураторсво второмследовательно и триггер отработает 2 раза
2 фев 05, 11:52    [1293524]     Ответить | Цитировать Сообщить модератору
 Re: Триггера  [new]
ange
Member

Откуда:
Сообщений: 181
нет, от такого общего запроса я ушла - именно вначале затираю, а потом пишу новое, потому как если объединить то эти операции будутвыполнятьвя в порядке следования записей в inserted, а здесь может получиться - вначале новое значение, а потом затирается
2 фев 05, 12:15    [1293638]     Ответить | Цитировать Сообщить модератору
 Re: Триггера  [new]
ange
Member

Откуда:
Сообщений: 181
еще один минус, почему хочу как-то выкрутиться - мало того что действия выполняются в два раза больше раз, чем нужно, но еще и в таблице аудита получаются лишние строки - боюсь совсем поперезапутаться
2 фев 05, 12:21    [1293670]     Ответить | Цитировать Сообщить модератору
 Re: Триггера  [new]
Smirnov Anton
Member

Откуда: Н.Новгород
Сообщений: 3220
CREATE Trigger EnterpriseCurator on T_UsersAccessToClient for update
as
set nocount on
begin
update t1 set Curator='' from t_enterprise t1 join 
(select inserted.* from inserted i inner join deleted d on i.c_id=d.c_id where i.IsCurator<>d.IsCurator and i.IsCurator=-1) t2 on (t1.area_id=t2.area_id)
and not exists (select IsCurator from inserted where IsCurator=1 and area_id=t1.area_id)

update t1 set Curator=t3.User_SurName + ' ' + t3.User_FirstName + ' ' + t3.User_PatronymicName
from t_enterprise t1 join 
(select inserted.* from inserted i inner join deleted d on i.c_id=d.c_id where i.IsCurator<>d.IsCurator and i.IsCurator=1) t2 on (t1.area_id=t2.area_id) join T_Users t3 on (t2.user_login=t3.user_login)
end
set nocount of
только я ещё раз повторяю, вам это навряд-ли поможнт, тк надо это делать на клиенте, ибо
1) сняли галку с одного
update T_UsersAccessToClient set IsCurator=-1 where ...
срабатывает триггер, обновляется t_enterprise, запись в аудит
2) поставили галку на другого
update T_UsersAccessToClient set IsCurator=1 where ...
срабатывает триггер, обновляется t_enterprise, запись в аудит
ЗЫ или я что-то недопоминаю
2 фев 05, 12:37    [1293740]     Ответить | Цитировать Сообщить модератору
 Re: Триггера  [new]
ange
Member

Откуда:
Сообщений: 181
неа, все понимаете
но вот в этом и вопрос каким бы таким образом придумать условие

если в обновлении есть замена кураторства с одного пользователя на другого
то выделяем эти сроки и заменяем сразу пользователь 1 на пользователь 2

если нет, то просто обновляем через ваш пример case when

в этом случае запрос на обновление будет только один
2 фев 05, 12:41    [1293761]     Ответить | Цитировать Сообщить модератору
 Re: Триггера  [new]
ange
Member

Откуда:
Сообщений: 181
или я чего-то не понимаю?
2 фев 05, 12:44    [1293779]     Ответить | Цитировать Сообщить модератору
 Re: Триггера  [new]
Smirnov Anton
Member

Откуда: Н.Новгород
Сообщений: 3220
я ж говорю, что задача в клиенте
этот вопрос нада придумать в реализации клиента
будь то кнопка "Сменить куратора" и тп
или не заносить сразу в базу, что они там наотмечали в чек боксах, не знаю
как вам больше понравится
2 фев 05, 12:49    [1293793]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить