Предыдущая тема :: Следующая тема |
Автор |
Сообщение |
astraboomer
Зарегистрирован: 02.03.2005 Сообщения: 10
|
Добавлено: Ср Май 11 2005 20:33 Заголовок сообщения: Помогите создать триггер в MS SQL |
|
|
Здравтсвуйте! Помогите решить проблему с триггерами в MS SQL 2000.
Есть 3 таблицы Filial (Id - автоинкрементное, Name), Race (Id - автоинкрементное, Name) и
Fil_Race (Id - автоинкрементное, Fil_Id, Race_Id, Name, Avail). Таблицы
Filial и Fil_Race имеют общее поле для связи (Filial.Id=Fil_Race.Fil_Id), а таблицы
Race и Race имеют общее поле для связи (Race.Id=Fil_Race.Race_Id). Необходимо
создать следующий триггер на вставку новой записи в таблицу Filial.
Id всех записей таблицы Race вставить в Fil_Race со зачением нового id
таблицы Filial.
Конкретно не могу решить вопрос по получению id новой
вставленной записи в Filial и вставке значений из поля всех
записей таблицы Race. |
|
Вернуться к началу |
|
|
Wladimir
Зарегистрирован: 02.03.2005 Сообщения: 150 Откуда: Ставропольский край
|
Добавлено: Ср Май 11 2005 20:46 Заголовок сообщения: |
|
|
Непонятно: "ВСЕХ записей Race" . Таки прямо всех для каждого филиала?
id добавляемых (ещё не обязательно добавленных) записей в Filial берёшь запросом из таблицы Inserted. В данном случае, видимо, в ней будет одна запись. |
|
Вернуться к началу |
|
|
astraboomer
Зарегистрирован: 02.03.2005 Сообщения: 10
|
Добавлено: Ср Май 11 2005 20:58 Заголовок сообщения: |
|
|
Wladimir писал(а): | Непонятно: "ВСЕХ записей Race" . Таки прямо всех для каждого филиала?
id добавляемых (ещё не обязательно добавленных) записей в Filial берёшь запросом из таблицы Inserted. В данном случае, видимо, в ней будет одна запись. |
Да, обязательно всех записей RAce. Насчет Inserted можно по подробней? |
|
Вернуться к началу |
|
|
Wladimir
Зарегистрирован: 02.03.2005 Сообщения: 150 Откуда: Ставропольский край
|
Добавлено: Чт Май 12 2005 08:57 Заголовок сообщения: |
|
|
В триггерах автоматически возникают две таблицы: Inserted и Deleted.
(аналог IB new и old)
Inserted содержит копии новые версии данных, Deleted - старые.
Соответственно
select Id from Inserted
даст тебе Id всех добавляемых на момент работы триггера элементов Filial. |
|
Вернуться к началу |
|
|
astraboomer
Зарегистрирован: 02.03.2005 Сообщения: 10
|
Добавлено: Чт Май 12 2005 14:47 Заголовок сообщения: |
|
|
Спасибо! Помогло. Но у меня добавилось условие. Если в
Fil_Race уже есть записи с добавляемым @fid, то тогда
добавлять не нужно в Fil_Race. Я пишу:
Код: | CREATE TRIGGER Filials_Insert ON [dbo].[Filials]
AFTER INSERT
AS
declare @fid int
select @fid = inserted.Id from inserted
if not exists (select * from Fil_Race where Fil_Race.Filial_Id=@fid)
begin
insert into Fil_Race (Filial_Id, Race_Id, BeginD, EndD) select @fid, Race.Id,
Race.BeginDate, Race.EndDate from Race
end |
Действительно, если в табл. Filial добавляется запись с
уже имеющемся в ней id (это поле не является ключом), то
ничего не происходит. А если добавляется запись с новым
id то происх. ошибка "Cannot insert the value NULL into column 'Id',
table dbo.Fil_Race; column does not allow nulls. Insert fails".
Не знаю почему может что-то не так написал?
Например табл. Filial:
Id Name
1 aaa
1 aaa_aaa
2 bbb
2 bbb_bbb
.........................
Если сейчас добавить запись с Id=2 то триггер не сработает,
а если с другим Id то возникнет эта ошибка. |
|
Вернуться к началу |
|
|
Wladimir
Зарегистрирован: 02.03.2005 Сообщения: 150 Откуда: Ставропольский край
|
Добавлено: Чт Май 12 2005 21:06 Заголовок сообщения: |
|
|
Состав полей в примере триггера отличается от указанного в вопросе.
Сообщение об ошибке указывает на то, что колонка Id объявлена как not null, но при этом не identity (т.е. не автоинкремент). Соответственно, когда ты её явно не заполняешь, в неё пытается попасть NULL, что запрещено.
Кстати, разумно Id сделать и primary key. |
|
Вернуться к началу |
|
|
astraboomer
Зарегистрирован: 02.03.2005 Сообщения: 10
|
|
Вернуться к началу |
|
|
Wladimir
Зарегистрирован: 02.03.2005 Сообщения: 150 Откуда: Ставропольский край
|
Добавлено: Пт Май 13 2005 07:33 Заголовок сообщения: |
|
|
Цитата: | Решение можно смотреть на |
Ну да, об чём и речь.
Кстати, решение половинчатое, работает только в случае добавления одной записи.
Если ты, например, сделаешь групповое добавление типа
insert into Filials select ... from откуда-то
, триггер отработает один раз (как ему в MsSql и положено - в отличие от IB), в Inserted будет несколько записей и конструкция с select @fid = ... не сработает.
Поэтому желательно это делать без промежуточной переменной. |
|
Вернуться к началу |
|
|
|