Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Не существует декларированная таблица в compound trigger. / 21 сообщений из 21, страница 1 из 1
29.11.2017, 23:07
    #39561643
Не существует декларированная таблица в compound trigger.
Доброго времени суток, уважаемые форумчане! Пытаюсь обойти мутирование таблиц путём создания 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
30.11.2017, 00:50
    #39561658
table()
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Не существует декларированная таблица в compound trigger.
Код: plsql
1.
            from dg_tab 

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

Нагородил... Зачем засовывать в коллекцию все договора со времен царя Гороха если все что нам нужно это запомнить 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
30.11.2017, 08:54
    #39561732
Не существует декларированная таблица в compound trigger.
table(), Здравствуйте! Извините, мне не совсем понятен ваш ответ, не могли бы вы разъяснить более подробно.
...
Рейтинг: 0 / 0
30.11.2017, 09:02
    #39561735
Не существует декларированная таблица в compound trigger.
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
30.11.2017, 09:25
    #39561745
Elic
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Не существует декларированная таблица в compound trigger.
Алексей КлименкоЯ так понимаю, Oracle считает процедуру COUNT для созданного типа данных не объявленной, стоит ли её объявить явно при создании типа, или есть дургое решение проблемы?Есть. Тебе рано ещё писать триггеры, а тем более составные.
Ты не понимаешь основ. Сперва надо сходить в ясли.
...
Рейтинг: 0 / 0
30.11.2017, 09:43
    #39561756
Stax
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Не существует декларированная таблица в compound trigger.
Алексей Клименко,

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

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

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

SY.
...
Рейтинг: 0 / 0
30.11.2017, 18:28
    #39562153
Не существует декларированная таблица в compound trigger.
Elic, буду признателен, если на эти самые ясли вы мне укажете. Но прошу понять, что на поспешность есть у меня причины. Отчаянные времена, отчаянные меры, как говорится.
...
Рейтинг: 0 / 0
30.11.2017, 18:29
    #39562158
Не существует декларированная таблица в compound trigger.
Stax, да, триггер скомпилируется, но работать не будет.
...
Рейтинг: 0 / 0
30.11.2017, 18:32
    #39562160
Не существует декларированная таблица в compound trigger.
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
30.11.2017, 18:36
    #39562162
Elic
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Не существует декларированная таблица в compound trigger.
Алексей КлименкоОтчаянные времена, отчаянные меры, как говорится.Говнокод, быдлокод, …
...
Рейтинг: 0 / 0
30.11.2017, 18:56
    #39562179
SY
SY
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Не существует декларированная таблица в compound trigger.
Алексей Клименко,

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

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

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

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

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

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



? TABLE(V_LIST)

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

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

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



? TABLE(V_LIST)

SY.

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

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

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


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