《基於ORACLE SQL優化》讀書筆記-遊標

show parameter open_cursors; --單個session可並存sessioncursor數

 

select count(*) from v$open_cursor where sid in (select sidfrom v$mystat where rownum<2);--當前session的sessioncursor總數

select name,value from v$sysstat where name ='opened cursorscurrent'; --open 狀態的session cursor總數

 

show parameter session_cached_cursors;

 

alter session set events 'immediate trace name ERRORSTACKlevel 3'; --session cursor dump

 

11gR2後,一個session cursor能夠緩存在PGA中的必要條件是該cursor所對應的SQL解析和執行的次數超過3次。

Pin這個動作是通過先持有與庫相關的Latch,再持有Library cache pin這個enqueue來實現。11gR1之前的版本,把CURSOR_SPACE_FOR_TIME的值設成TRUE,可以減少庫緩存相關的LATCH爭用,但會給Sharedpool空間帶來大的壓力。

 

隱式遊標:

1.      SQL%FOUND: SQL執行之後記錄的改變數是否大於1.(INSERT,UPDATE,DELETE,SELECTINTO)有TRUE,FALSE,NULL

2.      SQL%NOTFOUND

3.      SQL%ISOPEN 對隱式,總是FALSE

4.      SQL%ROWCUNT 記錄的改變數量

顯示遊標:

1.      CURSORNAME%FOUND

2.      CURSORNAME%NOTFOUND

3.      CURSORNAME%ISOPEN

4.      CURSORNAME%ROWCOUNT

參考遊標:

定義靈活,open方式靈活(不和固定的SQL綁定在一起),可作爲參數傳入。


select count(*) from v$open_cursor where sid in (select sid from v$mystat where rownum<2);
select name,value from v$sysstat where name ='opened cursors current';

show parameter session_cached_cursors;

alter session set events 'immediate trace name ERRORSTACK level 3';


select count(*)  from t52;

select sql_text,cursor_type from v$open_cursor where user_name='TESTER' and sid = 387 and sql_text like 'select count(*)  from t52';


select * from dept;
declare
 dept_no number(4) :=1;
 begin
 delete from dept where deptno = dept_no;
 if sql%found then
 insert into dept values(4,'DATABASE','bejing',current_date);
 end if;
 commit;
 end;
 /
select * from dept;

set serveroutput on size 1000000
declare
dept_name varchar2(14);
vc_message varchar2(4000);
begin
select dname into dept_name from dept where dname ='DATABASE';
exception
when no_data_found then
dbms_output.put_line('NO data found!');
return;
when too_many_rows then
dbms_output.put_line('Too many data');
return;
when others then
vc_message := 'E' ||'_'||sqlcode ||'_'||sqlerrm;
dbms_output.put_line(vc_message);
return;
end;
/


declare 
dept_no number(4) := 3;
begin
delete from dept where deptno =dept_no;
dbms_output.put_line('Number of departments deleted:'||to_char(sql%rowcount));
commit;
end;
/

declare 
cursor c1 is select ename,sal from emp where rownum <11;
my_ename emp.ename%type;
my_salary emp.sal%type;
begin
open c1;
loop 
fetch c1 into my_ename,my_salary;
if c1%found then
dbms_output.put_line('name=' || my_ename||',salary'||my_salary);
else
exit;
end if;
end loop;
close c1;
end;
/


exception
when others then
if c1%isopen = true then
close c1;
end if;

declare 
cursor c1 is select ename,sal from emp where rownum <11;
my_ename emp.ename%type;
my_salary emp.sal%type;
begin
open c1;
loop 
fetch c1 into my_ename,my_salary;
if c1%notfound then
exit;
else
dbms_output.put_line('name=' || my_ename||',salary'||my_salary);
end if;
end loop;
close c1;
end;
/

declare 
cursor c1 is select ename,sal from emp where rownum <11;
my_ename emp.ename%type;
my_salary emp.sal%type;
begin
open c1;
loop 
fetch c1 into my_ename,my_salary;
if c1%found then
dbms_output.put_line('name=' || my_ename||'_'||c1%rowcount);
else
exit;
end if;
end loop;
close c1;
end;
/




create or replace procedure DEMO_EXPLICIT_CURSOR is
--declare
cursor c1 is select ename,sal from emp where rownum <11;
emp_rec emp%rowtype;
begin
open c1;
fetch c1 into emp_rec;
while(c1%found) loop
dbms_output.put_line('name ='|| emp_rec.ename||',salary ='||emp_rec.sal);
fetch c1 into emp_rec;
end loop;
close c1;
exception 
when others then
--o_parm :='E' ||sqlcode ||sqlerrm;
rollback;
-- write log
return;
end DEMO_EXPLICIT_CURSOR;
/


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章