我们的项目中有一个巨大的Oracle SQL查询,它使用许多视图和表来获取源数据。
当我运行它时,有没有办法找到这个大查询从每个源表中提取的行列表?
基本上我们要做的是在源表中创建最小的行数,以便最外层的查询返回至少一条记录。
我试图单独运行较小的查询。但这真的很耗时且乏味。所以我想知道是否有更聪明的方法。
答案 0 :(得分:0)
您可以使用细粒度访问控制。您可以这样做:
步骤1:创建一个表来保存rowid列表(即您在本练习中寻找的结果)
CREATE TABLE matt_selected_rowids ( row_id rowid );
步骤2:创建一个FGAC处理程序,只要选择基表,就会添加一个谓词。
CREATE OR REPLACE PACKAGE matt_fgac_handler IS
FUNCTION record_rowid ( p_rowid rowid ) RETURN NUMBER DETERMINISTIC;
FUNCTION add_rowid_predicate (d1 varchar2, d2 varchar2 ) RETURN VARCHAR2;
END matt_fgac_handler;
CREATE OR REPLACE PACKAGE BODY matt_fgac_handler IS
FUNCTION record_rowid ( p_rowid rowid ) RETURN NUMBER DETERMINISTIC IS
PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
INSERT INTO matt_selected_rowids( row_id ) values ( p_rowid );
COMMIT;
RETURN -1;
END record_rowid;
FUNCTION add_rowid_predicate (d1 varchar2, d2 varchar2 ) RETURN VARCHAR2 IS
BEGIN
RETURN 'matt_fgac_handler.record_rowid (rowid) = -1';
END add_rowid_predicate;
END matt_fgac_handler;
步骤3:向您的视图使用的每个基表添加一个策略(您可以通过递归使用DBA_DEPENDENCI来获取列表,或者只是执行解释计划并进行眼球)。
如,
CREATE TABLE matt_table ( a number, b varchar2(80) );
CREATE INDEX matt_table_n1 on matt_table(a);
insert into matt_table values (1,'A');
insert into matt_table values (2,'B');
insert into matt_table values (3,'C');
insert into matt_table values (3,'D');
insert into matt_table values (3,'E');
insert into matt_table values (3,'F');
insert into matt_table values (4,'G');
insert into matt_table values (4,'H');
COMMIT;
BEGIN
DBMS_RLS.ADD_POLICY('APPS','MATT_TABLE','record_rowids_policy', NULL, 'matt_fgac_handler.add_rowid_predicate', 'select');
END;
所以,此时,只要用户从我的表中选择,Oracle就会自动添加一个为每个rowid调用record_rowid
函数的条件。
例如:
delete from matt_selected_rowids;
SELECT /*+ INDEX */ * FROM matt_table where a = 2;
-- This gives your the rowids selected...
select r.row_id, o.object_name from matt_selected_rowids r left join dba_objects o on o.object_id =dbms_rowid.rowid_object(row_id);