Предоставляет ли Oracle способ возврата нескольких подстрок из строки строки / clob, которая была проанализирована? - PullRequest
0 голосов
/ 12 ноября 2011

Я знаю, что есть функции REGEXP_, но они возвращают максимум 1 строку при простом применении к строке var.Я знаю, что вы можете использовать его в предложении WHERE, но мне нужен способ работы с большими строками / текстами / переменными clob, а не таблицами, поэтому я хотел бы знать, может ли какая-то функция возвращать несколько подстрок (я думаю о чем-токак взорваться () или - даже лучше - preg_match () в PHP).Как предложил APC, я предоставляю примерную строку и примеры результатов, которые я хотел бы получить. Как я уже говорил в комментариях ниже, я хочу получить тела функций / процедур (функции / процедуры, которые являются частью некоторых пакетов), такие какэто:

STRING:

  create or replace PACKAGE BODY export_db IS
  FUNCTION o_functie(ceva NUMBER) return boolean IS
  BEGIN
    RETURN null;
  END;
  FUNCTION o_functie(ceva NUMBER, altceva VARCHAR2) return boolean IS
  BEGIN
    RETURN null;
  END;
  PROCEDURE export_db_tabele IS
    v_ddl CLOB;
  BEGIN
      FOR c IN(SELECT object_type,object_name FROM user_objects where object_type IN ( 'TABLE')) LOOP
        v_ddl := v_ddl || dbms_metadata.get_ddl(c.object_type, c.object_name)||';'||CHR(13)||CHR(10);   
      END LOOP; 
      INSERT INTO dbexport(tipobiect, ddltext) VALUES ('tabele', v_ddl);
  END;
  PROCEDURE export_db_restrictii IS
    v_ddl CLOB;
  BEGIN
      FOR c IN(SELECT constraint_name FROM user_constraints) LOOP
        v_ddl := v_ddl || dbms_metadata.get_ddl('CONSTRAINT', c.constraint_name)||';'||CHR(13)||CHR(10);   
      END LOOP; 
      INSERT INTO dbexport(tipobiect, ddltext) VALUES ('restrictii', v_ddl);
  END;
  PROCEDURE export_db_secvente IS
    v_ddl CLOB;
  BEGIN
      FOR c IN(SELECT sequence_name FROM user_sequences) LOOP
        v_ddl := v_ddl || dbms_metadata.get_ddl('SEQUENCE', c.sequence_name)||';'||CHR(13)||CHR(10);   
      END LOOP; 
      INSERT INTO dbexport(tipobiect, ddltext) VALUES ('secvente', v_ddl);
  END;
  PROCEDURE export_db_proceduri IS
    v_ddl CLOB;
  BEGIN
      FOR c IN(SELECT OBJECT_NAME FROM user_objects up WHERE object_type = 'PROCEDURE') LOOP 
        v_ddl := v_ddl || dbms_metadata.get_ddl('PROCEDURE', c.OBJECT_NAME)||CHR(13)||CHR(10);   
      END LOOP;  
      INSERT INTO dbexport(tipobiect, ddltext) VALUES ('proceduri', v_ddl);
  END;
  PROCEDURE export_db_functii IS
    v_ddl CLOB;
  BEGIN
      FOR c IN(SELECT OBJECT_NAME FROM user_objects uo WHERE object_type = 'FUNCTION' ) LOOP 
         v_ddl := v_ddl || dbms_metadata.get_ddl('FUNCTION', c.OBJECT_NAME)||CHR(13)||CHR(10);   
      END LOOP; 
      INSERT INTO dbexport(tipobiect, ddltext) VALUES ('functii', v_ddl);
  END;
  PROCEDURE export_db_pachete IS
    v_ddl CLOB;
  BEGIN
      FOR c IN(SELECT OBJECT_NAME FROM user_objects uo WHERE object_type = 'PACKAGE' ) LOOP 
        v_ddl := v_ddl || dbms_metadata.get_ddl('PACKAGE', c.OBJECT_NAME)||CHR(13)||CHR(10);   
      END LOOP;   
      INSERT INTO dbexport(tipobiect, ddltext) VALUES ('pachete', v_ddl);
  END;
  PROCEDURE export_db_declansatoare IS
    v_ddl CLOB;
  BEGIN
      FOR c IN(SELECT OBJECT_NAME FROM user_objects uo WHERE object_type = 'TRIGGER' ) LOOP 
        v_ddl := v_ddl || dbms_metadata.get_ddl('TRIGGER', c.OBJECT_NAME)||CHR(13)||CHR(10);   
      END LOOP; 
      INSERT INTO dbexport(tipobiect, ddltext) VALUES ('declansatoare', v_ddl);
  END;
END;

ИТОГИ будут:

ex:

  FUNCTION o_functie(ceva NUMBER, altceva VARCHAR2) return boolean IS
  BEGIN
    RETURN null;
  END;

и

PROCEDURE export_db_secvente IS
    v_ddl CLOB;
  BEGIN
      FOR c IN(SELECT sequence_name FROM user_sequences) LOOP
        v_ddl := v_ddl || dbms_metadata.get_ddl('SEQUENCE', c.sequence_name)||';'||CHR(13)||CHR(10);   
      END LOOP; 
      INSERT INTO dbexport(tipobiect, ddltext) VALUES ('secvente', v_ddl);
  END;

Если вы знаете какой-либо другой метод получения этих процедур / функций, я рад отказаться от синтаксического анализа всего этого - насколько я знаю, - нет выбора для этого ... даже из таблиц user_source, user_procedures или других ...

1 Ответ

2 голосов
/ 12 ноября 2011

Нечто подобное может быть:

CREATE OR REPLACE FUNCTION explode(longline varchar)
  RETURN sys.dbms_debug_vc2coll PIPELINED
IS  
  pos PLS_INTEGER;
  lastpos PLS_INTEGER;
  element varchar(2000);
BEGIN
   lastpos := 1;
   pos := instr(longline, ',');

   while pos > 0 loop
      element := substr(longline, lastpos, pos - lastpos);
      lastpos := pos + 1;
      pos := instr(longline, ',', lastpos);
      pipe row(element);
   end loop;

   if lastpos <= length(longline) then
      pipe row (substr(longline, lastpos));
   end if;

   RETURN;
END;  
/

Это можно использовать так:

SQL> select * from table(explode('1,2,3'));

COLUMN_VALUE
---------------------------------------------
1
2
3
SQL>

Если вы не используете 11.x, вам нужно самостоятельно определить тип возвращаемого значения:

create type char_table as table of varchar(4000);

и измените объявление функции на:

CREATE OR REPLACE FUNCTION explode(longline varchar)
  RETURN char_table pipelined
.....
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...