Проверьте доступ к таблице для операторов Oracle SQL в BLOB - PullRequest
0 голосов
/ 07 сентября 2018

У меня есть таблица со столбцом, содержащим запрос SQL (только операторы select) в формате BLOB. Я пытаюсь найти способ проанализировать запросы SQL и проверить, к каким таблицам будут обращаться все запросы SQL.

Кто-нибудь делал что-нибудь подобное?

Сейчас я думаю создать цикл PLSQL, который:

  1. Преобразует BLOB в текст для получения запроса SQL
  2. Выполнить план объяснения для запроса
  3. Посмотрите на результат плана объяснения и получите все строки с помощью TABLE ACCESS

Редактировать: Я нахожусь в Oracle Database 11g Release 11.2.0.4.0 - 64-битная, если это помогает, и имею доступ только для чтения к базе данных, поэтому мне нужно будет создать решение, которое не будет навязываться БД.

Ответы [ 2 ]

0 голосов
/ 13 сентября 2018

Итак, вот как я это сделал:

DECLARE
  b BLOB;
  c CLOB;
  n NUMBER;

BEGIN

  -- << loop_through_table >>
  FOR o IN (SELECT TRIM(LABEL) lbl, REQUEST req FROM REQUEST_TABLE) LOOP

      b := o.req;
      IF ((b is null) OR (LENGTH(b)=0)) THEN
        DBMS_OUTPUT.PUT_LINE(o.lbl || ' : No query found');
        CONTINUE;
      END IF;

      -- Convert the BLOB to text to get the SQL query
      DBMS_LOB.CREATETEMPORARY(c,TRUE);
      n:=1;
      -- << loop_through_blob >>
      WHILE (n+32767<=LENGTH(b)) LOOP
        DBMS_LOB.WRITEAPPEND(c,32767,UTL_RAW.CAST_TO_VARCHAR2(DBMS_LOB.SUBSTR(b,32767,n)));
        n:=n+32767;
      END LOOP;
      DBMS_LOB.WRITEAPPEND(c,length(b)-n+1,UTL_RAW.CAST_TO_VARCHAR2(DBMS_LOB.SUBSTR(b,length(b)-n+1,n)));

      -- Execute explain plan
      execute immediate 'EXPLAIN PLAN SET STATEMENT_ID=''temp1'' FOR ' || c;

      -- Look at the result of the explain plan, and get all the lines of OBJECT_TYPE='TABLE'
      -- << loop_through_plan >>
      FOR p IN ( SELECT OBJECT_NAME FROM PLAN_TABLE WHERE STATEMENT_ID='temp1' AND OBJECT_TYPE='TABLE') LOOP
          DBMS_OUTPUT.PUT_LINE(o.lbl || ', ' || p.OBJECT_NAME);
      END LOOP;

      execute immediate 'DELETE FROM PLAN_TABLE WHERE STATEMENT_ID=''temp1'' ';

  END LOOP;
  DBMS_OUTPUT.PUT_LINE('-- Completed --');
END;
0 голосов
/ 07 сентября 2018

Это может быть еще один более простой метод.

Создание динамических представлений для этих SQL в поле BLOB.

EXECUTE IMMEDIATE 'CREATE OR REPLACE VIEW YOUR_VIEW_NAME AS '|| 
utl_raw.cast_to_varchar2(dbms_lob.substr(blob_field)); 

Запрос user_dependencies, чтобы получить именованные таблицы.

SELECT referenced_name AS table_name 
FROM   user_dependencies 
WHERE  type = 'VIEW' 
       AND NAME = 'YOUR_VIEW_NAME' 
       AND referenced_type = 'TABLE'; 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...