我需要限制查询可以为特定用户返回的行数。我知道我可以限制SQL查询,但我需要避免特定用户可以构建返回大量行的查询。因此我需要限制配置。
有人知道是否有可能吗?
答案 0 :(得分:1)
如果您有Enterprise Edition,则可以使用DBMS_RLS包实现VPD规则:
SQL> create or replace package pac1
2 is
3 function limit_rows(owner varchar2, tab varchar2) return varchar2;
4 end;
5 /
Package created.
SQL> create or replace package body pac1
2 is
3 function limit_rows(owner varchar2, tab varchar2) return varchar2
4 is
5 begin
6 return ' rownum <= 3';
7 end;
8 end pac1;
9 /
Package body created.
SQL> begin
2 dbms_rls.add_policy('HR','EMPLOYEES','RULE1','HR','PAC1.LIMIT_ROWS','SELECT');
3 end;
4 /
PL/SQL procedure successfully completed.
SQL> select first_name, last_name from hr.employees;
FIRST_NAME LAST_NAME
-------------------- -------------------------
Ellen Abel
Sundar Ande
Mozhe Atkinson
SQL>
答案 1 :(得分:0)
数据量不一定等于负载量。单行查询可以杀死数据库,如果它足够复杂的话。
对此的回答非常复杂。
您可以从中获取SQL并从中创建SQL PLAN,并从估计的成本和/或估计的行中获取该数据限制。
How To Create and Evolve a SQL Plan Baseline
How do I display and read the execution plans for a SQL statement
实施例: 我将创建一个临时表:
for header, values := range resp.Header {
for _, value := range values {
log.Printf("\t\t %s %s", header, value)
}
}
然后我使用Oracle的计划估算而没有实际运行查询
create table tmp_table2 as
select * from user_objects;
结果;
declare
l_sql varchar2 (32767);
begin
delete from plan_table;
l_sql := 'select * from tmp_table2';
execute immediate 'explain plan for ' || l_sql;
for i in (select cardinality,
cost,
bytes,
cpu_cost
from PLAN_TABLE
where operation = 'SELECT STATEMENT') loop
if i.cardinality /* rows */
> 500 then
dbms_output.put_line ('Too many rows');
elsif i.cpu_cost > 500000 then
dbms_output.put_line ('Too much CPU');
else
dbms_output.put_line ('About right');
end if;
end loop;
end;
或者您可以使用资源管理器限制每个会话:
答案 2 :(得分:0)
您可以使用游标实现此目的。见例:
SQL> create or replace function exec_query(sql_text varchar2) return sys_refcursor
2 is
3 num_rows number := 3;
4 c1 sys_refcursor;
5 begin
6 open c1 for 'with test as (' || sql_text || ') select * from test where rownum <=' || num_rows ;
7 return c1;
8 end;
9 /
Function created.
SQL> variable c1 refcursor;
SQL> exec :c1 := exec_query('select last_name, salary from hr.employees');
PL/SQL procedure successfully completed.
SQL> print :c1;
LAST_NAME SALARY
------------------------- ----------
King 24000
Kochhar 17000
De Haan 17000