powered by simpleCommunicator - 2.0.28     © 2024 Programmizd 02
Map
Форумы / Sybase ASA, ASE, IQ [игнор отключен] [закрыт для гостей] / Создание триггера обновляющего несколько строк в таблице
18 сообщений из 18, страница 1 из 1
Создание триггера обновляющего несколько строк в таблице
    #39856426
nastyaiwanowa21
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Версия сервера 11.0.1.3069.

Добрый день, пытаюсь написать триггер. Триггер срабатывает при обновлении поля MaintBudgetID или CompID в таблице Functions. После чего триггер должен обновить поле BudgetCodeDefID в таблице WorkOrder. Значение берется из поля MaintBudgetID (таблица Functions). Обновить нужно все строки, где поле CompID равны в обеих таблицах.

Создание таблицы Functions
Код: sql
1.
2.
3.
4.
5.
CREATE TABLE Functions
(FunctionID numeric (12) NOT NULL,
CompID numeric (12) NULL,
MaintBudgetID numeric (12) NULL,
PRIMARY KEY (FunctionID))



Заполнение таблицы Functions
Код: sql
1.
insert Functions values(100005321,100005329,null)



Создание таблицы WorkOrder
Код: sql
1.
2.
3.
4.
5.
CREATE TABLE WorkOrder
(WorkOrderID numeric (12) NOT NULL,
CompID numeric (12) NULL,
BudgetCodeDefID numeric (12) NULL,
PRIMARY KEY (WorkOrderID))



Заполнение таблицы WorkOrder
Код: sql
1.
2.
3.
insert Functions values(100005322,100005329,null)
insert Functions values(100005323,100005329,null)
insert Functions values(100005324,100005329,null)



Выполняем запрос для запуска триггера
Код: sql
1.
update amos.functions set maintbudgetid=100000014 where functionid=100005321



В результате чего в таблице WorkOrder должно обновиться 3 записи
WorkOrderID CompID BudgetCodeDefID100005322100005329100005321100005323100005329100005321100005324100005329100005321

Пишу триггер. Пытаюсь использовать курсоры, чтоб последовательно обновить каждую запись в таблице WorkOrder:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
CREATE TRIGGER "utru_Functions_MaintBudgetID"
AFTER UPDATE OF CompID, MaintBudgetID
ORDER 10 ON amos.Functions
REFERENCING OLD AS olddata NEW AS newdata
FOR EACH ROW
BEGIN
    IF user_name() != 'import' THEN
        IF newdata.CompID IS NOT NULL THEN
         begin			
            declare @WorkorderID numeric(12);
            declare CUR_CUSTOMER dynamic scroll cursor FOR 
                select WorkorderID 
                from amos.WorkOrder 
                where CompID = newdata.CompID;
            OPEN CUR_CUSTOMER;
            FETCH NEXT CUR_CUSTOMER INTO @WorkorderID;
            while (sqlcode = 0)
            loop 
                update amos.WorkOrder
                set BudgetCodeDefID = newdata.MaintBudgetID
                WHERE WorkorderID = @WorkorderID;
                FETCH NEXT CUR_CUSTOMER INTO @WorkorderID;
            end loop;
            CLOSE CUR_CUSTOMER;
         end;
        END IF;	
    END IF;
END



Но Sybase выдает мне ошибку
Код: sql
1.
2.
3.
4.
Could not execute statement.
SELECT returns more than one row
SQLCODE=-185, ODBC 3 State="HY000"
Line 1, column 1



Пожалуйста, подскажите что я делаю не так?
...
Рейтинг: 0 / 0
Создание триггера обновляющего несколько строк в таблице
    #39856459
Sergey Orlov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А зачем вам курсор, все 3-и значения известны, сделайте прямой update, если хочется побегать по курсору, то добавьте в него ключ, и обновляйте по ключу...
...
Рейтинг: 0 / 0
Создание триггера обновляющего несколько строк в таблице
    #39856551
KreatorXXI
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
nastyaiwanowa21,

подозреваю, схема данных у Вас ещё та. Не вариант сделать человеческий форейн-ключ с апдейтом?
...
Рейтинг: 0 / 0
Создание триггера обновляющего несколько строк в таблице
    #39856614
nastyaiwanowa21
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
1)
Sergey OrlovА зачем вам курсор, все 3-и значения известны, сделайте прямой update
Вы имеете в виду, что то такое? :
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
CREATE TRIGGER "utru_Functions_MaintBudgetID_StockBudgetID"
AFTER UPDATE OF CompID, MaintBudgetID
ORDER 10 ON amos.Functions
REFERENCING OLD AS olddata NEW AS newdata
FOR EACH ROW
BEGIN
    IF user_name() != 'import' THEN
        IF newdata.CompID IS NOT NULL THEN
            UPDATE  amos.WorkOrder
            SET     BudgetCodeDefID = newdata.MaintBudgetID
            WHERE   CompID = newdata.CompID;
        END IF;
    END IF;
END


Это первое, что я попробовала, но появилась ошибка:
Код: sql
1.
2.
3.
4.
Could not execute statement.
SELECT returns more than one row
SQLCODE=-185, ODBC 3 State="HY000"
Line 1, column 1


Поэтому попыталась использовать курсор, как написала выше, но это не помогло.

2)
Sergey Orlovдобавьте в него ключ, и обновляйте по ключу
Что Вы имеете в виду? Курсор и так пробегает по ключам WorkorderID.
Код: sql
1.
2.
3.
4.
declare CUR_CUSTOMER dynamic scroll cursor FOR 
   select WorkorderID 
   from amos.WorkOrder 
    where CompID = newdata.CompID;


3)KreatorXXIподозреваю, схема данных у Вас ещё та
Возможно, я только начинаю ее познавать.
4)KreatorXXIНе вариант сделать человеческий форейн-ключ с апдейтом?
Это самый крайний вариант.
...
Рейтинг: 0 / 0
Создание триггера обновляющего несколько строк в таблице
    #39856685
KreatorXXI
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
nastyaiwanowa21Это самый крайний вариант.
Почему самый крайний? Это самый правильный.
Если не хотите самый правильный, то сделайте простой update, типа:
Код: sql
1.
2.
3.
update WorkOrder
set WorkOrder.BudgetCodeDefID=new.MaintBudgetID
where WorkOrder.CompID=new.CompID


Использование курсоров здесь как-то ни к месту.
...
Рейтинг: 0 / 0
Создание триггера обновляющего несколько строк в таблице
    #39856726
nastyaiwanowa21
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
KreatorXXI,

Делала уже так. Выдает ошибку. Я подумала, что она появляется из-за того, что я пытаюсь обновить одновременно несколько записей, поэтому и добавила курсор. Но курсор не помог. Не понимаю, что ему нужно.
...
Рейтинг: 0 / 0
Создание триггера обновляющего несколько строк в таблице
    #39856751
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
nastyaiwanowa21,

а СУБД-то какая? ASA? ASE? IQ?
...
Рейтинг: 0 / 0
Создание триггера обновляющего несколько строк в таблице
    #39856753
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
nastyaiwanowa21,

Пока общее замечание не относящиеся к вопросу:

ВОт гляди:

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
            FETCH NEXT CUR_CUSTOMER INTO @WorkorderID;
            while (sqlcode = 0)
            loop 
                update amos.WorkOrder
                set BudgetCodeDefID = newdata.MaintBudgetID
                WHERE WorkorderID = @WorkorderID;
                FETCH NEXT CUR_CUSTOMER INTO @WorkorderID;
            end loop;
            CLOSE CUR_CUSTOMER;



Ни одной обработки ошибок!
...
Рейтинг: 0 / 0
Создание триггера обновляющего несколько строк в таблице
    #39856754
nastyaiwanowa21
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
KreatorXXI,

Из документации Sybase
You tried to use a SELECT statement without a cursor, but the statement cursor returns more than one row. Only a single row SELECT statement can be used in this context.

Я так поняла, что он ругается, что я не использую курсор. Разве нет?
...
Рейтинг: 0 / 0
Создание триггера обновляющего несколько строк в таблице
    #39856757
nastyaiwanowa21
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
MasterZiv,

MasterZivа СУБД-то какая? ASA? ASE? IQ?
ASA 11.
...
Рейтинг: 0 / 0
Создание триггера обновляющего несколько строк в таблице
    #39856797
Dim2000
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
02.09.2019 19:02, nastyaiwanowa21 пишет:

> declare @WorkorderIDnumeric(12);
> declare CUR_CUSTOMERdynamic scroll cursor FOR
> select WorkorderID
> from amos.WorkOrder
> where CompID = newdata.CompID;
> OPEN CUR_CUSTOMER;
> FETCH NEXT CUR_CUSTOMERINTO @WorkorderID;
> while (sqlcode = 0)
> loop
> update amos.WorkOrder
> set BudgetCodeDefID = newdata.MaintBudgetID
> WHERE WorkorderID = @WorkorderID;
> FETCH NEXT CUR_CUSTOMERINTO @WorkorderID;
> end loop;
> CLOSE CUR_CUSTOMER;

Зачем это кошмарное микрософтообразное уродство?
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Создание триггера обновляющего несколько строк в таблице
    #39856810
nastyaiwanowa21
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Dim2000,
авторЗачем это кошмарное микрософтообразное уродство?
Критикуешь - предлагай.
...
Рейтинг: 0 / 0
Создание триггера обновляющего несколько строк в таблице
    #39856872
Sergey Orlov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Для начала,
1. у вас что на таблице куча триггеров на одно событие update, это к тому что указан order 10, если один так уберите это служебное слово
2.
после begin сразу присвойте значения из new, примерно так
set tempCompID = newdata.CompID,
ну а дальше обрабатывайте записи в WorkOrder
...
Рейтинг: 0 / 0
Создание триггера обновляющего несколько строк в таблице
    #39856989
nastyaiwanowa21
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Sergey Orlov,
Sergey Orlov1. у вас что на таблице куча триггеров на одно событие update, это к тому что указан order 10, если один так уберите это служебное слово

Да, еще два, сформированы системой, которая использует эту базу.

Sergey Orlov2.
после begin сразу присвойте значения из new, примерно так
set tempCompID = newdata.CompID,
ну а дальше обрабатывайте записи в WorkOrder
Сделала так:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
CREATE TRIGGER "utru_Functions_MaintBudgetID_StockBudgetID"
AFTER UPDATE OF CompID, MaintBudgetID
ORDER 10 ON amos.Functions
REFERENCING OLD AS olddata NEW AS newdata
FOR EACH ROW
BEGIN

declare tempCompID numeric(12);
declare tempMaintBudgetID numeric(12);
set tempCompID = newdata.CompID;
set tempMaintBudgetID = newdata.MaintBudgetID;

    IF user_name() != 'import' THEN
        IF tempCompID IS NOT NULL THEN
            UPDATE  amos.WorkOrder
            SET     BudgetCodeDefID = tempMaintBudgetID
            WHERE   CompID = tempCompID;
        END IF;
    END IF;
END


Не помогло. Ошибка осталась.
...
Рейтинг: 0 / 0
Создание триггера обновляющего несколько строк в таблице
    #39857000
KreatorXXI
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
nastyaiwanowa21,

Ошибка про select с возвратом нескольких rows к "нашим" update'ам отношения не имеет. Наверняка ещё какой-то триггер с ошибкой. Естественно в таблице WorkOrder (которую апдейтят).
...
Рейтинг: 0 / 0
Создание триггера обновляющего несколько строк в таблице
    #39857439
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вообще, триггера -- это трындец.
Надо их запретить вообще.
...
Рейтинг: 0 / 0
Создание триггера обновляющего несколько строк в таблице
    #39858957
Sergey Orlov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
nastyaiwanowa21,
Только что обратил внимание на то, что вы делаете CREATE TRIGGER , все это работает, только, если триггера нет в базе, как только вы скрипт первый раз запустили, то триггер создался и если вы его хотите изменить, то Alter trigger... либо связка drop trigger ... create trigger... в противном случае ошибка...
...
Рейтинг: 0 / 0
Создание триггера обновляющего несколько строк в таблице
    #39860187
nastyaiwanowa21
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
KreatorXXI,
KreatorXXIОшибка про select с возвратом нескольких rows к "нашим" update'ам отношения не имеет. Наверняка ещё какой-то триггер с ошибкой. Естественно в таблице WorkOrder (которую апдейтят).

Вы правы. Дело было действительно в этом. До того как выполнялся мой триггер, на таблице workorder висел другой триггер, который выполнялся раньше его. И имел в себе функцию которая во вложенном под запросе возвращала более одной записи. Удалили лишнии записи все работает как и задумано.
...
Рейтинг: 0 / 0
18 сообщений из 18, страница 1 из 1
Форумы / Sybase ASA, ASE, IQ [игнор отключен] [закрыт для гостей] / Создание триггера обновляющего несколько строк в таблице
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]