2

まったく同じクエリであるが、いくつかの異なるテーブルに適用される多くのトリガーを更新するタスクがあります。FOR または同様のステートメントを使用して、これらすべての TRIGGERS を更新する方法はありますか? 実際に私がする必要があるのは、このすべてのトリガーの WHEN 句を変更することです。

4

2 に答える 2

3

これには dbms_metadat を使用できます。

例えば:

declare
  type arr_tab is table of varchar2(30);
  v_arr arr_tab;
  v_trig  clob;
begin
  dbms_metadata.set_transform_param( DBMS_METADATA.SESSION_TRANSFORM, 
                    'SQLTERMINATOR', FALSE );

  v_arr := arr_tab('TEST_TRIG', 'TEST2_TRIG'); -- change these triggers.
  for idx in 1..v_arr.count
  loop
    v_trig := dbms_metadata.get_ddl('TRIGGER',v_arr(idx), user);
    execute immediate regexp_replace(regexp_replace(v_trig, 'ALTER TRIGGER.*', ''), 'WHEN ([^\)]*\))', 'WHEN (1=1)', 1, 1, 'mi');
  end loop;
end;
/

この部分は、句を (私の場合) に'WHEN ([^\)]*\))', 'WHEN (1=1)'置き換えます。WHENWHEN (1=1)

于 2013-02-01T22:30:07.887 に答える
0

dba_triggers を使用して、トリガーのテキストを CREATE または replace ステートメントに抽出できます。ただし、一部の列が LONG データ型であるため、それらを VARCHAR2 として抽出する際に問題が発生します。これは、オラクル サイトのどこかにある Tom Kytes パッケージを使用することで解決できます。必要に応じて変更する必要があるかもしれない独自のバージョンを含めます。

select を実行し、when 句を挿入してから、create または replace ステートメントを実行します。

trigger_body が長いデータ型であるため、これは機能しません。

select 'CREATE OR REPLACE TRIGGER '|| description
||trigger_body
from dba_triggers
where owner = 'Your schema'

ただし、トリガーが4000文字を超えない場合、これは機能するはずです

select 'CREATE OR REPLACE TRIGGER '|| description
    || ADMIN.LONG_HELP.SUBSTR_OF('select trigger_body from dba_triggers where    trigger_name = :0',
1,4000,'0',dt.trigger_name)
from dba_triggers dt
where owner = 'YourSchema';


CREATE OR REPLACE PACKAGE ADMIN.LONG_HELP
   /******************************************************************************
      NAME:       LONG_HELP
      PURPOSE:    Read fields of type long.  (commonly found in data dictionary)

      REVISIONS:
      Ver        Date        Author           Description
      ---------  ----------  ---------------  ------------------------------------
      1.0        10/27/2011             1. Created this package. based on Tom Kyte's column here
      http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:839298816582
      note  that it only retrieves the first 4000 characters of any LONG column
      USAGE in a WHERE
      INSTR(
      ADMIN.LONG_HELP.SUBSTR_OF('SELECT text from all_views where view_name =:o ',
      1,4000,'o',m2.obj_name),m1.FK_ID) > 0

   ******************************************************************************/

   --AUTHID CURRENT_USER 
   --removed to get around ORA-29470: Effective userid or roles are not the same as when cursor was parsed
   --restrict usage to admin schema for Oracle 11g

AS
   FUNCTION substr_of (p_query   IN VARCHAR2,
                       p_from    IN NUMBER,
                       p_for     IN NUMBER,
                       p_name1   IN VARCHAR2 DEFAULT NULL ,
                       p_bind1   IN VARCHAR2 DEFAULT NULL ,
                       p_name2   IN VARCHAR2 DEFAULT NULL ,
                       p_bind2   IN VARCHAR2 DEFAULT NULL ,
                       p_name3   IN VARCHAR2 DEFAULT NULL ,
                       p_bind3   IN VARCHAR2 DEFAULT NULL ,
                       p_name4   IN VARCHAR2 DEFAULT NULL ,
                       p_bind4   IN VARCHAR2 DEFAULT NULL )
      RETURN VARCHAR2;
END LONG_HELP;
/
CREATE OR REPLACE PACKAGE BODY ADMIN.LONG_HELP
AS
   g_cursor   NUMBER := DBMS_SQL.open_cursor;
   g_query    VARCHAR2 (32765);


   PROCEDURE bind_variable (p_name IN VARCHAR2, p_value IN VARCHAR2)
   IS
   BEGIN
      IF (p_name IS NOT NULL)
      THEN
         DBMS_SQL.bind_variable (g_cursor, p_name, p_value);
      END IF;
   END BIND_VARIABLE;



   FUNCTION substr_of (p_query   IN VARCHAR2,
                       p_from    IN NUMBER,
                       p_for     IN NUMBER,
                       p_name1   IN VARCHAR2 DEFAULT NULL ,
                       p_bind1   IN VARCHAR2 DEFAULT NULL ,
                       p_name2   IN VARCHAR2 DEFAULT NULL ,
                       p_bind2   IN VARCHAR2 DEFAULT NULL ,
                       p_name3   IN VARCHAR2 DEFAULT NULL ,
                       p_bind3   IN VARCHAR2 DEFAULT NULL ,
                       p_name4   IN VARCHAR2 DEFAULT NULL ,
                       p_bind4   IN VARCHAR2 DEFAULT NULL )
      RETURN VARCHAR2
   AS
   /******************************************************************************
   NAME:       LONG_HELP.SUBSTR_OF
   PURPOSE:    CONVERT long data fields into VARCHAR2
   WHOSE DATA IS CHANGED: none
   WHAT USES THIS:
   WHERE ARE THE RESOURCES NEEDED:

******************************************************************************/
      l_buffer       VARCHAR2 (4000);
      l_buffer_len   NUMBER;
   BEGIN
      IF (NVL (p_from, 0) <= 0)
      THEN
         raise_application_error (-20002,
                                  'From must be >= 1 (positive numbers)');
      END IF;

      IF (NVL (p_for, 0) NOT BETWEEN 1 AND 4000)
      THEN
         raise_application_error (-20003, 'For must be between 1 and 4000');
      END IF;


      IF (p_query <> g_query OR g_query IS NULL)
      THEN
         IF (UPPER (TRIM (NVL (p_query, 'x'))) NOT LIKE 'SELECT%')
         THEN
            raise_application_error (-20001, 'This must be a select only');
         END IF;

         DBMS_SQL.parse (g_cursor, p_query, DBMS_SQL.native);
         g_query := p_query;
      END IF;

      bind_variable (p_name1, p_bind1);
      bind_variable (p_name2, p_bind2);
      bind_variable (p_name3, p_bind3);
      bind_variable (p_name4, p_bind4);

      DBMS_SQL.define_column_long (g_cursor, 1);

      IF (DBMS_SQL.execute_and_fetch (g_cursor) > 0)
      THEN
         DBMS_SQL.column_value_long (g_cursor,
                                     1,
                                     p_for,
                                     p_from - 1,
                                     l_buffer,
                                     l_buffer_len);
      END IF;

      RETURN l_buffer;
   END substr_of;
END LONG_HELP;
/
于 2013-02-01T19:30:39.100 に答える