Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Firebird, Interbase > Триггер на копирование записаей при вставке


Автор: Dimyan 22.2.2005, 11:45
Нигде не могу найти описания написания триггеров, точнее команд триггеров. В них вроде как я понял немного даже свой язык, т.е. не SQL применяется. А триггер надо срочно, помогите пожалуйста написать (а может за одно и ссылочку на документацию дадите)
Суть такова, при вставке в таблицу cars все записи должны копироватся в таблицу foo_cars
я навоял вот такое, но выдает ошибку (да и вообще я в правильности написанного не уверен)
Код

AS
begin
 INSERT INTO foo_cars VALUES(ID, OFFICE_ID, CAR_ID, SEND_DATA, RCV_DATA, CITI_ID, RPAY);
 POST_EVENT "INSERT INTO cars";
end

Автор: Alex 22.2.2005, 17:49
Код

AS
begin
INSERT INTO foo_cars VALUES(new.ID, new.OFFICE_ID, new.CAR_ID, new.SEND_DATA, new.RCV_DATA, new.CITI_ID, RPAY);
end

Добавлено @ 17:50
Скачай себе книгу http://delphisam.fatal.ru/Mir%20InterBase.rar.

Автор: Dimyan 23.2.2005, 08:29
Alex, сапсибо. Скачал почитал и еще много чего почитал, вроде разобрался, но не могу понять где ошибка
Код

AS
begin
  IF((select foo_cars.id_foo from foo_cars, cars where foo_cars.id = cars.id) <> 0)
  then DELETE from foo_cars where foo_cars.id = cars.id;

 INSERT INTO foo_cars(ID, OFFICE_ID, CAR_ID, SEND_DATA, RCV_DATA, CITY_ID, RPAY, METHOD)
  VALUES(new.ID, new.OFFICE_ID, new.CAR_ID, new.SEND_DATA, new.RCV_DATA, new.CITY_ID, new.RPAY, 2);
end

это триггер на апдейт и надо чтоб в таблице foo_cars была только единная запись измененной строки = cars.id
говорит SQL error code = -206.
пробывал вместо 0 поставить NULL в условии, но тогда говорит Parsing Error smile

Автор: Dimyan 23.2.2005, 09:19
Попробывал еще так
Код

AS
begin
  for select foo_cars.id_foo from foo_cars, cars where foo_cars.id = cars.id
  do
  begin
  delete from foo_cars where foo_cars.id = cars.id;
  end
 INSERT INTO foo_cars(ID, OFFICE_ID, CAR_ID, SEND_DATA, RCV_DATA, CITY_ID, RPAY, METHOD)
  VALUES(new.ID, new.OFFICE_ID, new.CAR_ID, new.SEND_DATA, new.RCV_DATA, new.CITY_ID, new.RPAY, 2);
end

тоже блин ошибка smile

Автор: Alex 23.2.2005, 10:08
А так:
Код

AS
begin
 IF (not ((select foo_cars.id_foo from foo_cars, cars where foo_cars.id = cars.id) is null)) then
DELETE from foo_cars where foo_cars.id = cars.id;

INSERT INTO foo_cars(ID, OFFICE_ID, CAR_ID, SEND_DATA, RCV_DATA, CITY_ID, RPAY, METHOD)
 VALUES(new.ID, new.OFFICE_ID, new.CAR_ID, new.SEND_DATA, new.RCV_DATA, new.CITY_ID, new.RPAY, 2);
end

Автор: Dimyan 23.2.2005, 11:10
Alex, а так
Цитата
Column does not belong to referenced table.
Dynamic SQL Error.
SQL error code = -206.
Subselect illegal in this context.


я вот так еще попробывал, но так при изменении записи сама сработка триггера выдает ошибку smile
Код

AS
begin
if (exists (select foo_cars.id_foo from foo_cars where foo_cars.id = cars.id)) then
  DELETE from foo_cars where foo_cars.id = cars.id;

 INSERT INTO foo_cars(ID, OFFICE_ID, CAR_ID, SEND_DATA, RCV_DATA, CITY_ID, RPAY, METHOD)
  VALUES(cars.ID, cars.OFFICE_ID, cars.CAR_ID, cars.SEND_DATA, cars.RCV_DATA, cars.CITY_ID, cars.RPAY, 2);
 
end

Автор: Alex 23.2.2005, 11:27
Цитата(Dimyan @ 23.2.2005, 11:10)
я вот так еще попробывал, но так при изменении записи сама сработка триггера выдает ошибку

Какую?

Автор: Dimyan 23.2.2005, 11:38
Alex, ну я же ниже код привел

Автор: Alex 23.2.2005, 12:11
Давай так поступим: пришли мне свою базу на alex собака vingrad.ru Очень трудно моделировать твои ситуации мне на своей тестовой базе.

Автор: Sleepy_PIP 23.2.2005, 20:29
Цитата(Dimyan @ 23.2.2005, 08:29)
Alex, сапсибо. Скачал почитал и еще много чего почитал, вроде разобрался, но не могу понять где ошибка
Код

AS
begin
  IF((select foo_cars.id_foo from foo_cars, cars where foo_cars.id = cars.id) <> 0)
  then DELETE from foo_cars where foo_cars.id = cars.id;

 INSERT INTO foo_cars(ID, OFFICE_ID, CAR_ID, SEND_DATA, RCV_DATA, CITY_ID, RPAY, METHOD)
  VALUES(new.ID, new.OFFICE_ID, new.CAR_ID, new.SEND_DATA, new.RCV_DATA, new.CITY_ID, new.RPAY, 2);
end

это триггер на апдейт и надо чтоб в таблице foo_cars была только единная запись измененной строки = cars.id
говорит SQL error code = -206.
пробывал вместо 0 поставить NULL в условии, но тогда говорит Parsing Error smile

блин. не очень понимаю чего ты хочешь.
может вот этого:
select count(foo_cars.id_foo) from foo_cars, cars into :cc where foo_cars.id = cars.id)

IF(cc<> 0)

а?

Автор: Dimyan 24.2.2005, 08:11
Sleepy_PIP, я хочу чтоб при изменении данных в таблице cars эти данные по триггеру вносились в foo_cars но при этом если в foo_cars уже есть запись которая соответствует условию foo_cars.id = cars.id то она предварительно удалялась

я попробывал
Код

select count(foo_cars.id_foo) from foo_cars, cars into :cc where foo_cars.id = cars.id)

IF(cc<> 0)


только переставил into
Код

select count(foo_cars.id_foo) into :cc from foo_cars, cars  where foo_cars.id = cars.id;

и не работает smile
при компиляции триггера выдается ошибка
Цитата

Invalid token.
Dynamic SQL Error.
SQL error code = -104.
Token unknown - line 12, char 35.
into.


smile

Автор: Sleepy_PIP 24.2.2005, 08:57
Цитата(Dimyan @ 24.2.2005, 08:11)
Sleepy_PIP, я хочу чтоб при изменении данных в таблице cars эти данные по триггеру вносились в foo_cars но при этом если в foo_cars уже есть запись которая соответствует условию foo_cars.id = cars.id то она предварительно удалялась

я попробывал
Код

select count(foo_cars.id_foo) from foo_cars, cars into :cc where foo_cars.id = cars.id)

IF(cc<> 0)


только переставил into
Код

select count(foo_cars.id_foo) into :cc from foo_cars, cars  where foo_cars.id = cars.id;

и не работает smile
при компиляции триггера выдается ошибка
Цитата

Invalid token.
Dynamic SQL Error.
SQL error code = -104.
Token unknown - line 12, char 35.
into.


smile

ну это все от того, что
1. - я ошибся. а зря.
2. - ты так и не почитал доков по IB.
т.к. конструкция с into должна быть такой как:
select count(acc) vv from accounts where acc='222' into :cc;

т.е. в твоем случае:
select count(foo_cars.id_foo) from foo_cars, cars where foo_cars.id = cars.id into :cc;

Автор: Alex 24.2.2005, 09:34
Цитата(Dimyan @ 24.2.2005, 08:11)
Sleepy_PIP, я хочу чтоб при изменении данных в таблице cars эти данные по триггеру вносились в foo_cars но при этом если в foo_cars уже есть запись которая соответствует условию foo_cars.id = cars.id то она предварительно удалялась

Погоди, так тогда я не совсем понимаю, зачем так все накручивать ведь при добавлении в таблицу cars ты уже заносишь данные триггером в таблицу foo_cars. Значит, при изменении данных в cars измени данные и в foo_cars. Не нужно делать никаких удалений сделай обычный update.

Автор: Dimyan 24.2.2005, 09:48
Alex, нет проблем, но таблица foo_cars очищается каждые 5 минут и что я буду обновлять в пустой foo_cars при изменении записи в cars?

Sleepy_PIP, хоть убей прочитал что мог и про "Вложенный SQL" даже, нигде нормально не описываются как использовать SQL с условиями и ветвлениями алгоритма. А по InterBase\FireBird я вообще все свободное от работы время читаю свеже купленную "Мир InterBase" 3-ие издание !

Автор: Sleepy_PIP 24.2.2005, 10:05
Цитата(Dimyan @ 24.2.2005, 09:48)
Alex, нет проблем, но таблица foo_cars очищается  каждые 5 минут и что я буду обновлять в пустой foo_cars при изменении записи в cars?

Sleepy_PIP, хоть убей прочитал что мог и про "Вложенный SQL" даже, нигде нормально не описываются как использовать SQL с условиями и ветвлениями алгоритма. А по InterBase\FireBird я вообще все свободное от работы время читаю свеже купленную "Мир InterBase" 3-ие издание !

Ух ты! уже 3-е издание! Спасибо за информацию.
Ну ты победил синтакс. ошибку?
PS: а я еще успешно пользовал полную док-цию от IB4 - там все расписано.

Автор: Dimyan 24.2.2005, 10:23
Sleepy_PIP, мне стыдно признаться но на into :cc говорит что "сс" неизвестное поле и я немогу понять как опредилить эту переменную или это только в через ХП надо делать?

Автор: Sleepy_PIP 24.2.2005, 10:31
Цитата(Dimyan @ 24.2.2005, 10:23)
Sleepy_PIP, мне стыдно признаться но на into :cc говорит что "сс" неизвестное поле и я немогу понять как опредилить эту переменную или это только в через ХП надо делать?

иэээх ... а говориш читал - там (2-е издание) - некое коллво примеров есть, и описаны и триггера (кратко очень) и самое главное - SP.
вообщем гляди, я привожу полный тескст гипотетического, на работающего триггреа:
Код

/******************************************************************************/
/***               Generated by IBExpert 24.02.2005 10:33:11                ***/
/******************************************************************************/

SET SQL DIALECT 3;

SET NAMES WIN1251;


SET TERM ^;




CREATE TRIGGER ACCOUNTS_BU0 FOR ACCOUNTS
ACTIVE BEFORE UPDATE POSITION 0
AS
declare variable cc integer;
begin
 /* Trigger text */
 select count(acc) vv  from accounts where acc='222' into :cc;
 if(cc<>0) then
 begin
   insert into accounts (acc,typ,idorg) values ('5555',1,1);
 end
end
^


SET TERM; ^



тут все видно. понимаешь?

Автор: Dimyan 24.2.2005, 12:04
Sleepy_PIP, да конечно, огромное спасибо

Автор: Sleepy_PIP 24.2.2005, 12:10
Цитата(Dimyan @ 24.2.2005, 12:04)
Sleepy_PIP, да конечно, огромное спасибо

да не за что. книжки конечно хорошие, но если будет возможность достать доки хотя-б от 4-ки - они тебе помогут.
А так-же не забывай проhttp://www.ibase.ru

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)