Oracle динамический SQL, найти используемые таблицы в запросе - PullRequest
0 голосов
/ 22 октября 2019

Есть ли способ найти список используемых таблиц в Oracle Dynamic SQL. Мне нужно установить ограничения для использования некоторых таблиц.

Пример для динамического текста запроса:

select *
  from Table1 T1
  join Table2 T2
    on T1.Col1 = T2.Col1
 where exists (select 1
          from Table3 T3
         where T1.Col2 = T3.Col2)

Результат должен быть: [Table1, Table2, Table3]. Есть идеи?

Ответы [ 3 ]

0 голосов
/ 22 октября 2019

Перенесите вашу строку для динамического SQL в оператор SQL SELECT, как показано ниже, чтобы извлечь имена таблиц, содержащихся в строке:

with t(str) as
(
 select 'select *
  from Table1 T1
  join Table2 T2
    on T1.Col1 = T2.Col1
 where exists (select 1
          from Table3 T3
         where T1.Col2 = T3.Col2)' from dual
), t2 as
(
  select level as row_num, regexp_substr(to_char(t.str),'^.*$',1,level,'m') as str
    from t
   connect by level <= length (to_char(t.str)) 
                     - length (replace (to_char(t.str), chr (10))) + 1 
), t3 as
(
select regexp_substr(
           regexp_substr(str,'From[[:space:]].*[[:space:]]',1,1,'i'),
                        '[^ ]+',1,2) as x,
       regexp_substr(
           regexp_substr(str,'Join[[:space:]].*[[:space:]]',1,1,'i'),
                        '[^ ]+',1,2) as y
  from t2 
)
select coalesce(x,y) as "Tables"
  from t3
 where coalesce(x,y) is not null;

Tables
-------
Table1
Table2
Table3 

Демо

0 голосов
/ 23 октября 2019

Список таблиц, используемых оператором SQL, может быть создан с использованием DBMS_UTILITY.EXPAND_SQL_TEXT, временного представления, и запрос DBA_DEPENDENCIES.

DBMS_UTILITY.EXPAND_SQL_TEXT заботится о поиске таблиц, на которые ссылаются представления. Временное представление и DBA_DEPENDENCIES затем генерируют список всех таблиц, используемых в расширенном операторе SQL.

Функция

create or replace function get_dependent_tables_from_sql(p_sql varchar2)
return sys.odcivarchar2list authid current_user is
    v_expanded_sql clob;
    v_tables sys.odcivarchar2list := sys.odcivarchar2list();
    pragma autonomous_transaction;
begin
    --Expand the SQL, which will go through all the recursive dependencies.
    dbms_utility.expand_sql_text
    (
        input_sql_text  => p_sql,
        output_sql_text => v_expanded_sql
    );

    --Create a view with the expanded SQL.
    execute immediate
    '
        create or replace view temp_view_for_dependencies as
        select count(*) the_count
        from
        (
        '||v_expanded_sql||'
        )
    ';

    --Find dependencies.
    --(Use execute immediate to simplify compilation privileges.)
    execute immediate
    q'[
        select distinct referenced_owner||'.'||referenced_name
        from dba_dependencies
        where name = 'TEMP_VIEW_FOR_DEPENDENCIES'
            and owner = user
            and referenced_type = 'TABLE'
    ]'
    bulk collect into v_tables;

    return v_tables;
end get_dependent_tables_from_sql;
/

Пример схемы

create table table1(col1 number, col2 number);
create table table2(col1 number, col2 number);
create table table3(col1 number, col2 number);
create table table4(col1 number, col2 number);
create table table5(col1 number, col2 number);
create or replace view view1 as select 1 a from dual;

Вызовfunction

select column_value table_name
from table(get_dependent_tables_from_sql(q'[
        select *
        from table1 t1
        --ANSI joins
        join table2 t2
            on t1.col1 = t2.col1
        where exists
        (
            select 1
            --Oracle style joins, views.
            from table3 t3, table4, view1
            where t1.col2 = t3.col2
        )
        --A table that won't be in execution plan.
        and exists (select 1 from table5 where 1 = 2)   
    ]'))
order by 1;

TABLE_NAME
----------
JHELLER.TABLE1
JHELLER.TABLE2
JHELLER.TABLE3
JHELLER.TABLE4
JHELLER.TABLE5
SYS.DUAL

Предупреждения о других решениях

Будьте осторожны с решениями, которые включают пользовательский анализ SQL. Это одна из тех проблем, которая выглядит обманчиво легкой. Вы можете создать регулярное выражение, которое работает в 98% случаев, но буквально невозможно создать регулярное выражение, которое работает в 100% случаев.

Будьте осторожны, используя решения плана выполнения. Отследить объекты плана выполнения обратно в таблицы не так просто, как если бы использовался только индекс. И некоторые таблицы могут быть использованы в запросе, но исключены из плана выполнения из-за исключения соединения.

0 голосов
/ 22 октября 2019

"Есть ли способ найти список используемых таблиц в Oracle Dynamic SQL".

Нет. То есть без чугуна и прямого пути. Одним из последствий динамического SQL является повышенная сложность анализа влияния.

Это правда, что вы можете найти некоторые имена таблиц, встроенные в буквенные строки в исходном коде.

select *
from user_source
where lower(text) like '%table1%'
or  lower(text) like '%table2%'
or  lower(text) like '%table3%'

Очевидно, вам нужно очистить вывод, чтобы изолировать имена таблиц, и, возможно, обработать ложные срабатывания на table17 и table23.

Однако, этоДинамический SQL обычно работает с таблицами, имена которых передаются в виде строк параметров во время выполнения или запрашиваются из словаря данных. Вряд ли вы сможете поймать все это. Очевидно, что размер этого разрыва зависит от того, как вы используете динамический SQL: возможно, у вас все будет хорошо.

Если ваша организация платит за пакеты настройки и диагностики, вы можете использовать ASH , чтобы найтиисполняемые идентификаторы SQL, которые можно проанализировать, чтобы найти соответствующие таблицы, и, если повезет, также угадать код, который сгенерировал и выполнил SQL.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...