powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Не существует декларированная таблица в compound trigger.
21 сообщений из 21, страница 1 из 1
Не существует декларированная таблица в compound trigger.
    #39561643
Доброго времени суток, уважаемые форумчане! Пытаюсь обойти мутирование таблиц путём создания compound триггера. На этапе компиляции возникает ошибка, "table or view does not exist". Что я хотел сделать: в statement триггере выбрать данные в таблицу, в each row триггере обратиться к ней запросом.
Средства: Oracle 11g R2, APEX 5.1.3.00.05.
Код: plsql
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.
29.
30.
31.
create or replace trigger "DOGOVOR_S_KANDIDATOM_SAME_PROF"
for
insert or update on "DOGOVOR_S_KANDIDATOM"
compound trigger
    type dg_rec_type is record (data DOGOVOR_S_KANDIDATOM.DATA_DOGOVORA%type, idProf DOGOVOR_S_KANDIDATOM.PROFESSII_IDPROFESSII%type);
    type dg_tab_type is table of dg_rec_type index by varchar2(30);
    dg_tab dg_tab_type;
    n pls_integer;
BEFORE STATEMENT IS
    begin
    dg_tab.delete;
    for rec in (select IDDOGOVOR_S_KANDIDATOM, DATA_DOGOVORA, PROFESSII_IDPROFESSII FROM DOGOVOR_S_KANDIDATOM) LOOP
        dg_tab(rec.IDDOGOVOR_S_KANDIDATOM).data := rec.DATA_DOGOVORA;
        dg_tab(rec.IDDOGOVOR_S_KANDIDATOM).idProf := rec.PROFESSII_IDPROFESSII;
        null;
    end loop;
end BEFORE STATEMENT;
AFTER EACH ROW IS
    BEGIN
        DBMS_OUTPUT.ENABLE;
        select count(*)
        into n
        from (Select dg_tab.data
            from dg_tab
            Where :NEW.PROFESSII_IDPROFESSII = dg_tab.idProf
            group by dg_tab.data
            having TO_CHAR(:NEW.DATA_DOGOVORA, 'MM') = TO_CHAR(dg_tab.data, 'MM'));
        htp.p('Количество претендентов на ту же должность'||n);
        NULL;
    END AFTER EACH ROW;
end "DOGOVOR_S_KANDIDATOM_SAME_PROF";
...
Рейтинг: 0 / 0
Не существует декларированная таблица в compound trigger.
    #39561658
table()
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Код: plsql
1.
            from dg_tab 

SQL Reference/Functions
...
Рейтинг: 0 / 0
Не существует декларированная таблица в compound trigger.
    #39561678
Фотография SY
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Алексей Клименко,

Нагородил... Зачем засовывать в коллекцию все договора со времен царя Гороха если все что нам нужно это запомнить IdProf и DATA из INSERT/UPDATE?

1. Создаем обьектный тип. Предположу PROFESSII_IDPROFESSII имеет тип NUMBER:

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
CREATE OR REPLACE
  TYPE DG_OBJ_TYPE
    AS OBJECT(
              DATA DATE,
              IdProf NUMBER
             )
/
CREATE OR REPLACE
  TYPE DG_TBL_TYPE
    AS TABLE OF DG_OBJ_TYPE
/



2. В триггере cоздаем переменную типа DG_TBL_TYPE:

V_LIST DG_TBL_TYPE := DG_TBL_TYPE();

3. В FOR EACH ROW:

V_LIST.COUNT;
V_LIST(V_LIST.COUNT).DATA := :NEW.DATA_DOGOVORA;
V_LIST(V_LIST.COUNT).IdProf := :NEW.PROFESSII_IDPROFESSII;

3. В AFTER STATEMENT:

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
FOR V_REC IN (
              SELECT  D.PROFESSII_IDPROFESSII,
                      TRUNC(D.DATA_DOGOVORA,'MM') DATA
                      COUNT(*) CNT
                FROM  DOGOVOR_S_KANDIDATOM D,
                      TABLE(V_LIST) T
                WHERE D.PROFESSII_IDPROFESSII = T.idProf
                  AND TRUNC(D.DATA_DOGOVORA,'MM') = TRUNC(T.data,'MM')
                GROUP BY D.PROFESSII_IDPROFESSII,
                         TRUNC(D.DATA_DOGOVORA,'MM')
             ) LOOP
  HTP.P('Количество претендентов на должность ' V_REC.PROFESSII_IDPROFESSII || ' за ' || TO_CHAR(V_REC.DATA,'FMMonth YYYY: ') || V_REC_CNT);
END LOOP;



Но все это от лукавого. Триггер животное транзакционное. Посему если несолько сессий всталяют договора на ту же IdProf то они не увидят остальных если на момент проверки остальные еще не закончили (commit) свои транзакции. Так-что без сериализации (а посему без потери производительности) не обойтись.

SY.
...
Рейтинг: 0 / 0
Не существует декларированная таблица в compound trigger.
    #39561732
table(), Здравствуйте! Извините, мне не совсем понятен ваш ответ, не могли бы вы разъяснить более подробно.
...
Рейтинг: 0 / 0
Не существует декларированная таблица в compound trigger.
    #39561735
SY, Добрый день! Большое спасибо за помощь! Я сделал всё, как вы советовали, исправив некоторые ошибки: пропущена одна запятая, один символ конкатенации, и вместо нижнего подчеркивания нужно было использовать точку. Но столкнулся с еще одной проблемой, "'COUNT' is not a procedure or is undefined". Я так понимаю, Oracle считает процедуру COUNT для созданного типа данных не объявленной, стоит ли её объявить явно при создании типа, или есть дургое решение проблемы?
Код: plsql
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.
29.
30.
create or replace trigger "DOGOVOR_S_KANDIDATOM_SAME_PROF"
for
insert or update on "DOGOVOR_S_KANDIDATOM"
compound trigger
V_LIST DG_TBL_TYPE := DG_TBL_TYPE();
BEFORE EACH ROW IS
    BEGIN
        DBMS_OUTPUT.ENABLE;
        V_LIST.COUNT;
        V_LIST(V_LIST.COUNT).DATA := :NEW.DATA_DOGOVORA;
        V_LIST(V_LIST.COUNT).IdProf := :NEW.PROFESSII_IDPROFESSII;
        NULL;
    END BEFORE EACH ROW;
AFTER STATEMENT IS
    begin
    FOR V_REC IN (
              SELECT  D.PROFESSII_IDPROFESSII,
                      TRUNC(D.DATA_DOGOVORA,'MM') DATA,
                      COUNT(*) CNT
                FROM  DOGOVOR_S_KANDIDATOM D,
                      TABLE(V_LIST) T
                WHERE D.PROFESSII_IDPROFESSII = T.idProf
                  AND TRUNC(D.DATA_DOGOVORA,'MM') = TRUNC(T.data,'MM')
                GROUP BY D.PROFESSII_IDPROFESSII,
                         TRUNC(D.DATA_DOGOVORA,'MM')
             ) LOOP
      HTP.P('Количество претендентов на должность '|| V_REC.PROFESSII_IDPROFESSII || ' за ' || TO_CHAR(V_REC.DATA,'FMMonth YYYY: ') || V_REC.CNT);
    END LOOP;
end AFTER STATEMENT;
end "DOGOVOR_S_KANDIDATOM_SAME_PROF";
...
Рейтинг: 0 / 0
Не существует декларированная таблица в compound trigger.
    #39561745
Фотография Elic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Алексей КлименкоЯ так понимаю, Oracle считает процедуру COUNT для созданного типа данных не объявленной, стоит ли её объявить явно при создании типа, или есть дургое решение проблемы?Есть. Тебе рано ещё писать триггеры, а тем более составные.
Ты не понимаешь основ. Сперва надо сходить в ясли.
...
Рейтинг: 0 / 0
Не существует декларированная таблица в compound trigger.
    #39561756
Фотография Stax
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Алексей Клименко,

если -- V_LIST.COUNT; закоментировать ушибка уходит?

.....
stax
...
Рейтинг: 0 / 0
Не существует декларированная таблица в compound trigger.
    #39562063
Фотография SY
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Алексей Клименко,

Oops,
Замени V_LIST.COUNT; нa V_LIST.EXTEND;

SY.
...
Рейтинг: 0 / 0
Не существует декларированная таблица в compound trigger.
    #39562153
Elic, буду признателен, если на эти самые ясли вы мне укажете. Но прошу понять, что на поспешность есть у меня причины. Отчаянные времена, отчаянные меры, как говорится.
...
Рейтинг: 0 / 0
Не существует декларированная таблица в compound trigger.
    #39562158
Stax, да, триггер скомпилируется, но работать не будет.
...
Рейтинг: 0 / 0
Не существует декларированная таблица в compound trigger.
    #39562160
SY, триггер скомпилировался, но при попытке обновления поля таблицы возникают ошибки.
Код: plsql
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.
29.
create or replace trigger "DOGOVOR_S_KANDIDATOM_SAME_PROF"
for
insert or update on "DOGOVOR_S_KANDIDATOM"
compound trigger
V_LIST DG_TBL_TYPE := DG_TBL_TYPE();
BEFORE EACH ROW IS
    BEGIN
        V_LIST.EXTEND;
        V_LIST(V_LIST.COUNT).DATA := :NEW.DATA_DOGOVORA;
        V_LIST(V_LIST.COUNT).IdProf := :NEW.PROFESSII_IDPROFESSII;
        NULL;
    END BEFORE EACH ROW;
AFTER STATEMENT IS
    begin
    FOR V_REC IN (
              SELECT  D.PROFESSII_IDPROFESSII,
                      TRUNC(D.DATA_DOGOVORA,'MM') DATA,
                      COUNT(*) CNT
                FROM  DOGOVOR_S_KANDIDATOM D,
                      TABLE(V_LIST) T
                WHERE D.PROFESSII_IDPROFESSII = T.idProf
                  AND TRUNC(D.DATA_DOGOVORA,'MM') = TRUNC(T.data,'MM')
                GROUP BY D.PROFESSII_IDPROFESSII,
                         TRUNC(D.DATA_DOGOVORA,'MM')
             ) LOOP
      HTP.P('Количество претендентов на должность '|| V_REC.PROFESSII_IDPROFESSII || ' за ' || TO_CHAR(V_REC.DATA,'FMMonth YYYY: ') || V_REC.CNT);
    END LOOP;
end AFTER STATEMENT;
end "DOGOVOR_S_KANDIDATOM_SAME_PROF";
...
Рейтинг: 0 / 0
Не существует декларированная таблица в compound trigger.
    #39562162
Фотография Elic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Алексей КлименкоОтчаянные времена, отчаянные меры, как говорится.Говнокод, быдлокод, …
...
Рейтинг: 0 / 0
Не существует декларированная таблица в compound trigger.
    #39562179
Фотография SY
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Алексей Клименко,

Упс еще раз. Забыл что элемeнт коллекции еcть обьект и посему тоже должен быть инициализиован. Замени:

Код: plsql
1.
2.
        V_LIST(V_LIST.COUNT).DATA := :NEW.DATA_DOGOVORA;
        V_LIST(V_LIST.COUNT).IdProf := :NEW.PROFESSII_IDPROFESSII;



на:

Код: plsql
1.
        V_LIST(V_LIST.COUNT) := DG_OBJ_TYPE(:NEW.DATA_DOGOVORA,:NEW.PROFESSII_IDPROFESSII);



Код: plsql
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.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
SQL> create table DOGOVOR_S_KANDIDATOM(
  2                                    IDDOGOVOR_S_KANDIDATOM NUMBER,
  3                                    PROFESSII_IDPROFESSII NUMBER,
  4                                    DATA_DOGOVORA DATE
  5                                   )
  6  /

Table created.

SQL> create or replace trigger "DOGOVOR_S_KANDIDATOM_SAME_PROF"
  2  for
  3  insert or update on "DOGOVOR_S_KANDIDATOM"
  4  compound trigger
  5  V_LIST DG_TBL_TYPE := DG_TBL_TYPE();
  6  BEFORE EACH ROW IS
  7      BEGIN
  8          V_LIST.EXTEND;
  9          V_LIST(V_LIST.COUNT) := DG_OBJ_TYPE(:NEW.DATA_DOGOVORA,:NEW.PROFESSII_IDPROFESSII);
 10          NULL;
 11      END BEFORE EACH ROW;
 12  AFTER STATEMENT IS
 13      begin
 14      FOR V_REC IN (
 15                    SELECT  D.PROFESSII_IDPROFESSII,
 16                            TRUNC(D.DATA_DOGOVORA,'MM') DATA,
 17                            COUNT(*) CNT
 18                      FROM  DOGOVOR_S_KANDIDATOM D,
 19                            TABLE(V_LIST) T
 20                      WHERE D.PROFESSII_IDPROFESSII = T.idProf
 21                        AND TRUNC(D.DATA_DOGOVORA,'MM') = TRUNC(T.data,'MM')
 22                      GROUP BY D.PROFESSII_IDPROFESSII,
 23                               TRUNC(D.DATA_DOGOVORA,'MM')
 24                   ) LOOP
 25        DBMS_OUTPUT.PUT_LINE(
 26                             'Number of candidates for job '|| V_REC.PROFESSII_IDPROFESSII ||
 27                             ' in ' || TO_CHAR(V_REC.DATA,'FMMonth YYYY: ') || V_REC.CNT
 28                            );
 29      END LOOP;
 30  end AFTER STATEMENT;
 31  end "DOGOVOR_S_KANDIDATOM_SAME_PROF";
 32  /

Trigger created.

SQL> SET SERVEROUTPUT ON
SQL> INSERT INTO DOGOVOR_S_KANDIDATOM
  2  VALUES(1,1,SYSDATE)
  3  /
Number of candidates for job 1 in November 2017: 1

1 row created.

SQL> INSERT INTO DOGOVOR_S_KANDIDATOM
  2  VALUES(2,1,SYSDATE)
  3  /
Number of candidates for job 1 in November 2017: 2

1 row created.

SQL> 



SY.
...
Рейтинг: 0 / 0
Не существует декларированная таблица в compound trigger.
    #39562180
Elic, ИМХО, Его можно избежать после n-го количества часов(месяцев? лет?) практики, а когда нужно наваять что-то для лабы, а до конца семестра осталось не так уж и много, то может быть конечно и грех это, но готов согрешить. Другой же способ избежать быдлокода, на мой взгляд, обратиться к более опытным товарищам за помощью, ради чего и пришел сюда.
...
Рейтинг: 0 / 0
Не существует декларированная таблица в compound trigger.
    #39562183
Фотография andrey_anonymous
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Алексей Клименко ради чего и пришел сюда.
Ну тогда следует попробовать работу триггера при параллельной вставке в двух или более сессиях.
Отдельно - при bulk-вставке (к примеру, insert select)
Осознать свою вину, меру, степень, глубину.
Поставить задачу как она должна быть решена, а не как показалось студенту ("обойти мутирование").
И спросить.
...
Рейтинг: 0 / 0
Не существует декларированная таблица в compound trigger.
    #39562191
SY, Большое спасибо, всё получилось.
...
Рейтинг: 0 / 0
Не существует декларированная таблица в compound trigger.
    #39562198
andrey_anonymous, Цель одна - сдать лабораторную. Если в процессе её достижения, или же волею случая при дальнейшей работе с oracle-ом вообще(хотя господа, вероятно, не хотели бы меня видеть и вовсе в рядах коллег своих по причине быдлокодерства), столкнусь с чем-то описанным вами, то обязательно вернусь сюда.
...
Рейтинг: 0 / 0
Не существует декларированная таблица в compound trigger.
    #39562201
Фотография Stax
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SY,

зачем SQL-ные типы?

імхо, compound удобен тем что не надо создавать пакетные переменные

.....
stax
...
Рейтинг: 0 / 0
Не существует декларированная таблица в compound trigger.
    #39562217
Фотография SY
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
StaxSY,

зачем SQL-ные типы?

імхо, compound удобен тем что не надо создавать пакетные переменные



? TABLE(V_LIST)

SY.
...
Рейтинг: 0 / 0
Не существует декларированная таблица в compound trigger.
    #39562257
Фотография Stax
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SYStaxSY,

зачем SQL-ные типы?

імхо, compound удобен тем что не надо создавать пакетные переменные



? TABLE(V_LIST)

SY.

так жеш бес табле можно ж

.....
stax
...
Рейтинг: 0 / 0
Не существует декларированная таблица в compound trigger.
    #39562302
Фотография SY
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
В цикле? Можно-то можно, да триггер штука не из дешевых а тут еще выполнять select N раз.

SY.
...
Рейтинг: 0 / 0
21 сообщений из 21, страница 1 из 1
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Не существует декларированная таблица в compound trigger.
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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