我有一个表,其中包含一个包含BLOB格式的SQL查询(仅限select语句)的列。我正试图找出一种分析SQL查询的方法,并检查每个SQL查询将访问哪些表。
有人做过类似的事吗?
我现在的想法是创建一个PLSQL循环:
编辑:我使用的是Oracle Database 11g 11.2.0.4.0版 - 64位如果有帮助,并且对数据库具有只读权限,那么我需要创建一个不会干扰数据库的解决方案。
这可能是另一种更简单的方法。
在BLOB字段中为这些SQL创建动态视图。
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';
那么,我就是这样做的:
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;