2

関数のソース コードから関数の CRUD マトリックスを作成しようとしているので、ソース コードを読み取るプロシージャを作成しました。

create or replace procedure test_ 
IS
  CURSOR c_text is 
    SELECT USER_SOURCE.TEXT 
      FROM USER_SOURCE 
     WHERE USER_SOURCE.name='TEST_FUNCTION' 
       AND USER_SOURCE.type='FUNCTION';
     order by line;

  v_single_text varchar2(4000);
  v_tmp_text varchar2(10000) := ' ';
begin
  open c_text;
  loop
   fetch c_text into v_single_text;
   exit when c_text%notfound;
   v_tmp_text := v_tmp_text|| chr(10) || rtrim(v_single_text);
   dbms_output.put_line(v_single_text);
  end loop;
  close c_text;
end test_;

そして、それは私にとって非常にうまく機能します。目的の関数のソースコードを取得できます。これは非常に単純な関数で、私はこれを使用して PL/SQL を学習しています。その手順の出力は次のようになります。

function test_funkction Return varchar2
IS
  kpp_value varchar2(20); 
begin
  select KPP 
    into kpp_value 
    from CUSTOMER 
   where CUSTOMER_ID = 200713;

  dbms_output.put_line (kpp_value);
  Return kpp_value;
end test_function;

さて、出力で得た文字列を解析して目的の結果を得る方法、私の結果は次のようになります

==TABLE_NAME==========OPERATIONS==

  CUSTOMER              - R - -

==================================

今、私はそれを行うことができました。

しかし、それは私の単純な関数でしか機能しません。今度は、どの関数でも機能するプロシージャを作成したいと思います。以下ソースコード。

create or replace procedure test_


IS


v_string_fnc varchar2(10000) := UPPER('function test_function



Return varchar2

IS

kpp_value varchar2(20);



  begin



  select KPP into kpp_value from CUSTOMER where CUSTOMER_ID = 200713;



  dbms_output.put_line (kpp_value);



 Return kpp_value;



 end test_function;');


 v_check PLS_INTEGER;


 CURSOR c_text is
 SELECT USER_SOURCE.TEXT
 FROM USER_SOURCE
 WHERE USER_SOURCE.name = 'TEST_FUNCTION'
 AND USER_SOURCE.type = 'FUNCTION'
 order by line;


 v_single_text varchar2(4000);
 v_tmp_text    varchar2(10000) := ' ';


 /*v_string      varchar2(10000);*/


 insert_flag char := '-';
 read_flag   char := '-';
 update_flag char := '-';
 delete_flag char := '-';
 empty_space char(34) := '                             ';
 underline   char(42) := '==========================================';


 /*v_txt         varchar2(10000) := ' ';*/


 result_table varchar2(1000) := '/';


 begin


 open c_text;


 loop
 fetch c_text
 into v_single_text;
 exit when c_text%notfound;
 v_tmp_text := v_tmp_text || chr(10) || rtrim(v_single_text);

/* print source code*/
/*dbms_output.put_line(v_single_text);*/

 end loop;


 close c_text;


 /*DELETE SEARCH*/


 v_check := instr(v_string_fnc, 'DELETE ');


 if v_check < 1 then
 dbms_output.put_line('THERE IS NO DELETE COMMAND');
 else
 dbms_output.put_line('THERE IS A DELETE COMMAND');
 delete_flag  := 'D';
 v_check      := instr(v_string_fnc, 'FROM ');
 v_check      := v_check + 5;
 result_table := substr(v_string_fnc, v_check);
 result_table := substr(result_table, 0, instr(result_table, ' '));
 dbms_output.put_line('TABLE AFFECTED BY DELETE: ' || result_table);
 end if;


 /*SELECT SEARCH*/


 v_check := instr(v_string_fnc, 'SELECT ');
 if v_check < 1 then
 dbms_output.put_line('THERE IS NO READ COMMAND');
 else
 dbms_output.put_line('THERE IS A READ COMMAND');
 read_flag    := 'R';
 v_check      := instr(v_string_fnc, 'FROM ');
 v_check      := v_check + 5;
 result_table := substr(v_string_fnc, v_check);
 result_table := substr(result_table, 0, instr(result_table, ' '));
 dbms_output.put_line('TABLE AFFECTED BY READ: ' || result_table);

 end if;


 /*UPDATE SEARCH*/
 v_check := instr(v_string_fnc, 'UPDATE ');
 if v_check < 1 then
 dbms_output.put_line('THERE IS NO UPDATE COMMAND');
 else
 dbms_output.put_line('THERE IS A UPDATE COMMAND');
 update_flag  := 'U';
 v_check      := instr(v_string_fnc, 'FROM ');
 v_check      := v_check + 5;
 result_table := substr(v_string_fnc, v_check);
 result_table := substr(result_table, 0, instr(result_table, ' '));
 dbms_output.put_line('TABLE AFFECTED BY UPDATE: ' || result_table);

 end if;


 /*INSERT SEARCH*/
 v_check := instr(v_string_fnc, 'INSERT ');
 if v_check < 1 then
 dbms_output.put_line('THERE IS NO CREATE COMMAND');
 else
 dbms_output.put_line('THERE IS A CREATE COMMAND');
 insert_flag  := 'C';
 v_check      := instr(v_string_fnc, 'FROM ');
 v_check      := v_check + 5;
 result_table := substr(v_string_fnc, v_check);
 result_table := substr(result_table, 0, instr(result_table, ' '));
 dbms_output.put_line('TABLE AFFECTED BY CREATE: ' || result_table);
 end if;
 dbms_output.put_line(' ');
 dbms_output.put_line('==========' || 'TABLE_NAME' || '==========' ||
                   'OPERATIONS' || '==');
 dbms_output.put_line(empty_space || insert_flag || read_flag ||
                   update_flag || delete_flag);
 dbms_output.put_line(underline);


 end test_;

この手順を使用すると、コードを抽出して出力できます。dbms は少しクリーンアップする必要がありますが、必要な結果が得られます。私の関数のソースコードを事前定義されていない変数に配置する方法について、いくつか質問があります。ここでは v_string_fnc ですが、機能するには事前定義する必要があります。そして、特定の操作をテーブルにリンクする方法は、ここで私の例では簡単です.1つのSELECTとキーワードFROMがテーブルの名前を与えます. 苦労は続く

4

1 に答える 1

1

大まかな部分は完了です。この後は調整のみです。

v_check := instr2(v_string_fnc, 'DROP ');

if v_check > 0 then

  delete_flag  := 'D';
  v_check      := instr2(v_string_fnc, 'TABLE ', v_check);
  v_check      := v_check + 6;
  result_table := substr(v_string_fnc, v_check);
  rest_string  := result_table;
  result_table := substr(result_table, 0, instr(result_table, ' '));
  result_table := rtrim(result_table);
  result_table := rtrim(result_table, ';');
  merge into result_set
  using dual
  on (tables_used = result_table)
  when matched then
    update set drop_operation = delete_flag
  when not matched then
    insert
      (tables_used, drop_operation)
    values
      (result_table, delete_flag);

  while v_check > 0 loop

    v_check := instr2(rest_string, 'DROP ');

    if v_check > 0 then
      delete_flag  := 'D';
      v_check      := instr2(rest_string, 'TABLE ', v_check);
      v_check      := v_check + 6;
      result_table := substr(rest_string, v_check);
      rest_string  := result_table;
      result_table := substr(result_table, 0, instr(result_table, ' '));
      result_table := rtrim(result_table);
      result_table := rtrim(result_table, ';');
      merge into result_set
      using dual
      on (tables_used = result_table)
      when matched then
        update set drop_operation = delete_flag
      when not matched then
        insert
          (tables_used, drop_operation)
        values
          (result_table, delete_flag);
    end if;
  end loop;
end if;
于 2013-09-30T09:53:59.980 に答える