powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Oracle [игнор отключен] [закрыт для гостей] / :OLD, :NEW в динамическом SQL
10 сообщений из 10, страница 1 из 1
:OLD, :NEW в динамическом SQL
    #32044151
PSERG
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Можно-ли это осуществить, если можно, то как?
...
Рейтинг: 0 / 0
:OLD, :NEW в динамическом SQL
    #32044383
vskv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Huh?
А зачем это тебе?

Первый селект
Код: plaintext
1.
2.
3.
select chego_to_tam OLD
from gde_to_tam
where chto_to_tam;


...update...

Второй селект
Код: plaintext
1.
2.
3.
select novoje_chego_to_tam NEW
from gde_to_tam
where chto_to_tam;
...
Рейтинг: 0 / 0
:OLD, :NEW в динамическом SQL
    #32044389
vskv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Или тебе нужно что-то иное, типа использования динамического SQL в триггере?
...
Рейтинг: 0 / 0
:OLD, :NEW в динамическом SQL
    #32044660
PSERG
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Именно о тригере и идет речь.
Нужно что-то типа
execute immediate 'insert into table1( col1, col2)values(:new.col1, :new.col2);
...
Рейтинг: 0 / 0
:OLD, :NEW в динамическом SQL
    #32044679
nick
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
ну тогда и пиши
execute immediate 'insert into table1( col1, col2)values('|| :new.col1||','|| :new.col2||')';
если :new.col1 строковое, то довавь необходимое кол-во кавычек или вообще используй DBMS_SQL
...
Рейтинг: 0 / 0
:OLD, :NEW в динамическом SQL
    #32044847
PSERG
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Все дело в том что заранее не известны столбцы таблицы.
Я формирую строку инсерта на основании данных из sys.all_tab_columns
...
Рейтинг: 0 / 0
:OLD, :NEW в динамическом SQL
    #32045217
Ramil
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Что значит неизвестны? Это же из триггера на таблицу, а в нем ты не можешь не знать типы полей .....
...
Рейтинг: 0 / 0
:OLD, :NEW в динамическом SQL
    #32045390
vskv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вы случаем не пытаетесь решить проблему универсального журналирующего триггера?
То есть такого, который сам бы адаптировался к изменению структуры таблицы на которую повешен???
Если да, то поделитесь результатом, please...
...
Рейтинг: 0 / 0
:OLD, :NEW в динамическом SQL
    #32098190
m_kus
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Предлагаю возобновить тему :-)) Обладатели Oracle ниже 8i, могут не беспокоиться и дальше не читать...

У меня тут бредовая мысль... Например, хочется знать все изменения в некоторой схеме (у меня она совпадает с ником m_kus ).
Пишу что-то подобное:
Код: plaintext
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.
CREATE OR REPLACE PACKAGE Logs AS

  FieldSeparator CONSTANT VARCHAR2( 3 ) := '###';
  DefDateFormat VARCHAR2( 20 ) := 'DD.MM.YYYY HH24:MI';
  PROCEDURE WriteStr(String IN VARCHAR2);

  PROCEDURE WriteField(FieldName IN VARCHAR2, Value IN VARCHAR2);  /* OVERLOAD */ 

  PROCEDURE WriteField(FieldName IN VARCHAR2, Value IN DATE,
                         DateFormat IN VARCHAR2 DEFAULT DefDateFormat);  /* OVERLOAD */ 

  PROCEDURE WriteField(FieldName IN VARCHAR2, Value IN NUMBER);  /* OVERLOAD */ 

  PROCEDURE WriteField(FieldName IN VARCHAR2, Value IN CLOB);  /* OVERLOAD */ 

END Logs;
/

CREATE OR REPLACE PACKAGE BODY Logs AS

  PROCEDURE WriteStr(String IN VARCHAR2) IS
  BEGIN
    какая нибудь запись, в файл, таблицу или...
  END;

  PROCEDURE WriteField(FieldName IN VARCHAR2, Value IN VARCHAR2)  /* OVERLOAD */  IS
  BEGIN
    WriteStr(FieldName || '=' || Value || FieldSeparator);
  END;

  PROCEDURE WriteField(FieldName IN VARCHAR2, Value IN DATE,
                         DateFormat IN VARCHAR2 DEFAULT DefDateFormat)  /* OVERLOAD */  IS
  BEGIN
    WriteStr(FieldName || '=' || TO_CHAR(Value,DateFormat) || FieldSeparator);
  END;

  PROCEDURE WriteField(FieldName IN VARCHAR2, Value IN NUMBER)  /* OVERLOAD */  IS
  BEGIN
    WriteStr(FieldName || '=' || TO_CHAR(Value) || FieldSeparator);
  END;

  PROCEDURE WriteField(FieldName IN VARCHAR2, Value IN CLOB)  /* OVERLOAD */  IS
  BEGIN
    WriteStr(FieldName || '=' || DBMS_LOB.SUBSTR(Value) || FieldSeparator);
  END;

END Logs;



Далее создаю такой триггер на создание/изменение/удаление таблицы:
Код: plaintext
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.
CREATE OR REPLACE TRIGGER TrLogTriggersCreate AFTER CREATE OR ALTER OR DROP ON m_kus. SCHEMA
BEGIN
  DBMS_OUTPUT.enable( 4000 );
  IF ora_sysevent='DROP' THEN
    DBMS_OUTPUT.put_line('DROP TRIGGER TrLog' || ora_dict_obj_name || ';');
  ELSE
    DBMS_OUTPUT.put_line('CREATE OR REPLACE TRIGGER TrLog' || ora_dict_obj_name || ' AFTER INSERT OR UPDATE OR DELETE ON m_kus.' || ora_dict_obj_name);
    DBMS_OUTPUT.put_line(' BEGIN ');
    DBMS_OUTPUT.put_line(' IF INSERTING OR UPDATING THEN');
    FOR tcur IN (SELECT * FROM user_tab_columns WHERE TABLE_NAME=ora_dict_obj_name) LOOP
      DBMS_OUTPUT.put_line('  IF (INSERTING AND (:new.' || tcur.COLUMN_NAME || ' IS NOT NULL)) OR (UPDATING(' || tcur.COLUMN_NAME || ')) THEN');
      DBMS_OUTPUT.put_line('    Logs.WriteField("' || tcur.COLUMN_NAME || '", :new.' || tcur.COLUMN_NAME || ')');
      DBMS_OUTPUT.put_line('  END;');
    END LOOP;
    DBMS_OUTPUT.put_line(' ELSE');
    DBMS_OUTPUT.put_line('    Logs.WriteStr("Deleting odnako")');
    DBMS_OUTPUT.put_line(' END;');
    DBMS_OUTPUT.put_line(' END;/');
  END IF;
   --EXECUTE IMMEDIATE Command;
 
EXCEPTION
  WHEN OTHERS THEN
    DBMS_OUTPUT.put_line('Trigger not [re]constructed!');
END;
/


Этот триггер генерирует другой триггер, который достаточно подвесить на созданную таблицу (к сожалению мне не удалось создать его с помощью EXECUTE COMMAND, где Command собрана из строчек, выведенных на экран)...

Вот, всё не идеально, требует доработки и т.д. Например, можно из соответствующих представлений читать данные о первичном ключе и эти поля писать каким-либо отдельным образом... По разному можно производить саму запись в лог (по записи на поле или одну запись в лог на одну изменяемую запись) и т. д.
Естественно, надо чтобы таблица с логом была в отдлельной схеме или на неё триггер не создавался... :))
Можно сделать вспомогательные таблицы, в которых перечислены таблицы (и поля), которые подвережены записи в лог.
Если не удасться запускать прямо из триггера, тогда можно и так:
Код: plaintext
1.
2.
3.
4.
5.
6.
  CREATE OR REPLACE MyDDL(Statement IN VARCHAR2)
  IS
  BEGIN
    EXECUTE IMMEDIATE Statement;
    как-нибудь захватить вывод и выполнить его...
  END;
но не знаю, как вывод захватывать в PL/SQL...
Правда это всё уже ничуть не лучше ручного запуска процедуры генерирующей триггер процедуры (возможность её написания я не подвергаю сомнения), что уже не так удобно, так как не всякий оболочку типа ErWin-а можно заставить изменить сценарий создания таблицы...

Хочу выслушать ваши мнения и предложения, может кто-то видел/использовал что-то подобное, так пусть просвятит...
...
Рейтинг: 0 / 0
:OLD, :NEW в динамическом SQL
    #32098249
Фотография Oleg Afanasiev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
У меня по крайней мере не получилось и пришлось перечислять столбцы.
Проблема в том что :NEW он видит как незабиндинную :_) переменную.
Конструкция ведь такая же... как ему объяснить?
...
Рейтинг: 0 / 0
10 сообщений из 10, страница 1 из 1
Форумы / Oracle [игнор отключен] [закрыт для гостей] / :OLD, :NEW в динамическом SQL
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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