Гость
Map
Форумы / Sybase ASA, ASE, IQ [игнор отключен] [закрыт для гостей] / Создание триггера обновляющего несколько строк в таблице / 18 сообщений из 18, страница 1 из 1
02.09.2019, 19:02
    #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
02.09.2019, 22:55
    #39856459
Sergey Orlov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Создание триггера обновляющего несколько строк в таблице
А зачем вам курсор, все 3-и значения известны, сделайте прямой update, если хочется побегать по курсору, то добавьте в него ключ, и обновляйте по ключу...
...
Рейтинг: 0 / 0
03.09.2019, 11:21
    #39856551
KreatorXXI
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Создание триггера обновляющего несколько строк в таблице
nastyaiwanowa21,

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


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

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

а СУБД-то какая? ASA? ASE? IQ?
...
Рейтинг: 0 / 0
03.09.2019, 16:47
    #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
03.09.2019, 16:47
    #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
03.09.2019, 16:50
    #39856757
nastyaiwanowa21
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Создание триггера обновляющего несколько строк в таблице
MasterZiv,

MasterZivа СУБД-то какая? ASA? ASE? IQ?
ASA 11.
...
Рейтинг: 0 / 0
03.09.2019, 17:56
    #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
03.09.2019, 18:07
    #39856810
nastyaiwanowa21
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Создание триггера обновляющего несколько строк в таблице
Dim2000,
авторЗачем это кошмарное микрософтообразное уродство?
Критикуешь - предлагай.
...
Рейтинг: 0 / 0
03.09.2019, 21:02
    #39856872
Sergey Orlov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Создание триггера обновляющего несколько строк в таблице
Для начала,
1. у вас что на таблице куча триггеров на одно событие update, это к тому что указан order 10, если один так уберите это служебное слово
2.
после begin сразу присвойте значения из new, примерно так
set tempCompID = newdata.CompID,
ну а дальше обрабатывайте записи в WorkOrder
...
Рейтинг: 0 / 0
04.09.2019, 10:34
    #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
04.09.2019, 10:50
    #39857000
KreatorXXI
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Создание триггера обновляющего несколько строк в таблице
nastyaiwanowa21,

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

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


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