Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Oracle [игнор отключен] [закрыт для гостей] / :OLD, :NEW в динамическом SQL / 10 сообщений из 10, страница 1 из 1
19.08.2002, 07:38
    #32044151
PSERG
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
:OLD, :NEW в динамическом SQL
Можно-ли это осуществить, если можно, то как?
...
Рейтинг: 0 / 0
19.08.2002, 23:44
    #32044383
vskv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
:OLD, :NEW в динамическом SQL
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
20.08.2002, 02:08
    #32044389
vskv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
:OLD, :NEW в динамическом SQL
Или тебе нужно что-то иное, типа использования динамического SQL в триггере?
...
Рейтинг: 0 / 0
20.08.2002, 16:34
    #32044660
PSERG
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
:OLD, :NEW в динамическом SQL
Именно о тригере и идет речь.
Нужно что-то типа
execute immediate 'insert into table1( col1, col2)values(:new.col1, :new.col2);
...
Рейтинг: 0 / 0
20.08.2002, 17:13
    #32044679
nick
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
:OLD, :NEW в динамическом SQL
ну тогда и пиши
execute immediate 'insert into table1( col1, col2)values('|| :new.col1||','|| :new.col2||')';
если :new.col1 строковое, то довавь необходимое кол-во кавычек или вообще используй DBMS_SQL
...
Рейтинг: 0 / 0
21.08.2002, 11:50
    #32044847
PSERG
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
:OLD, :NEW в динамическом SQL
Все дело в том что заранее не известны столбцы таблицы.
Я формирую строку инсерта на основании данных из sys.all_tab_columns
...
Рейтинг: 0 / 0
22.08.2002, 13:51
    #32045217
Ramil
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
:OLD, :NEW в динамическом SQL
Что значит неизвестны? Это же из триггера на таблицу, а в нем ты не можешь не знать типы полей .....
...
Рейтинг: 0 / 0
23.08.2002, 05:20
    #32045390
vskv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
:OLD, :NEW в динамическом SQL
Вы случаем не пытаетесь решить проблему универсального журналирующего триггера?
То есть такого, который сам бы адаптировался к изменению структуры таблицы на которую повешен???
Если да, то поделитесь результатом, please...
...
Рейтинг: 0 / 0
29.01.2003, 14:39
    #32098190
m_kus
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
:OLD, :NEW в динамическом SQL
Предлагаю возобновить тему :-)) Обладатели 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
29.01.2003, 15:26
    #32098249
Oleg Afanasiev
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
:OLD, :NEW в динамическом SQL
У меня по крайней мере не получилось и пришлось перечислять столбцы.
Проблема в том что :NEW он видит как незабиндинную :_) переменную.
Конструкция ведь такая же... как ему объяснить?
...
Рейтинг: 0 / 0
Форумы / Oracle [игнор отключен] [закрыт для гостей] / :OLD, :NEW в динамическом SQL / 10 сообщений из 10, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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