當前位置:編程學習大全網 - 圖片素材 - 數據庫裏面靜態遊標包含哪兩種類型?

數據庫裏面靜態遊標包含哪兩種類型?

遊標是SQL的壹個內存工作區,由系統或用戶以變量的形式定義。遊標的作用就是用於臨時存儲從數據庫中提取的數據塊。Oracle數據庫的Cursor類型包含三種: 靜態遊標:分為顯式(explicit)遊標和隱式(implicit)遊標;REF遊標:是壹種引用類型,類似於指針。下面我們壹壹介紹它們的使用。

1.隱式遊標

1)Select …INTO…語句,DML語句,使用隱式Cursor。此外,還有壹種使用FOR LOOP的Implicit Cursor用法。

2)可以通過隱式Cusor的屬性來了解操作的狀態和結果。Cursor的屬性包含:

SQL%ROWCOUNT 整型代表DML語句成功執行的數據行數。

SQL%FOUND 布爾型值為TRUE代表插入、刪除、更新或單行查詢操作成功。

SQL%NOTFOUND 布爾型與SQL%FOUND屬性返回值相反。

SQL%ISOPEN 布爾型DML執行過程中為真,結束後為假。

3) 隱式Cursor由系統自動打開和關閉.

例如:

setserveroutputon

declare

begin

updateemployeessetemployee_name='Mike'whereemployee_id=1001;

ifSQL%FOUNDthen

dbms_output.put_line('Nameisupdated');

else

dbms_output.put_line('Nameisnotupdated');

endif;

end;

/

setserveroutputon

declare

begin

fortableInfoin(select*fromuser_tables)loop

dbms_output.put_line(tableInfo.table_name);

endloop;

exception

whenothersthen

dbms_output.put_line(sqlerrm);

end;

/

2.顯式遊標

1) 顯式Cursor的屬性包含:

遊標的屬性 返回值類型 意義

%ROWCOUNT 整型 獲得FETCH語句返回的數據行數

%FOUND 布爾型 最近的FETCH語句返回壹行數據則為真,否則為假

%NOTFOUND 布爾型 與%FOUND屬性返回值相反

%ISOPEN 布爾型 遊標已經打開時值為真,否則為假

2) 對於顯式遊標的運用分為四個步驟:

a 定義遊標---Cursor [Cursor Name] IS;

b 打開遊標---Open [Cursor Name];

c 操作數據---Fetch [Cursor name]

d 關閉遊標---Close [Cursor Name]

以下是幾種常見顯式Cursor用法。

<p>setserveroutputon

declare

cursorcurisselect*fromuser_tables;

tableInfouser_tables%rowtype;

begin

opencur;

loop

fetchcurintotableInfo;

exitwhencur%notfound;

dbms_output.put_line(tableInfo.table_name);

endloop;</p><p>exception

whenothersthen

dbms_output.put_line(sqlerrm);</p><p>closecur;

end;

/</p>

setserveroutputon

declare

cursorcurisselect*fromuser_tables;

begin

fortableInfoincurloop

dbms_output.put_line(tableInfo.table_name);

endloop;

exception

whenothersthen

dbms_output.put_line(sqlerrm);

end;

/

還可以使用帶參數open的cursor。

<p>setserveroutputon

declare

cursorcur(tblNamevarchar2)isselect*fromuser_constraintswheretable_name=tblName;

tableInfouser_constraints%rowtype;

begin

opencur('EMPLOYEES');

loop

fetchcurintotableInfo;

exitwhencur%notfound;

dbms_output.put_line(tableInfo.constraint_name);

endloop;</p><p>exception

whenothersthen

dbms_output.put_line(sqlerrm);</p><p>closecur;

end;

/</p><p></p>

setserveroutputon

declare

cursorcur(tblNamevarchar2)isselect*fromuser_constraintswheretable_name=tblName;

begin

fortableInfoincur('EMPLOYEES')loop

dbms_output.put_line(tableInfo.constraint_name);

endloop;

exception

whenothersthen

dbms_output.put_line(sqlerrm);

end

/

可以使用WHERE CURRENT OF子句執行UPDATE或DELETE操作。

setserveroutputon

declare

cursorcurisselect*fromemployeesforupdate;

begin

fortableInfoincurloop

updateemployeessetsalarysalary=salary*1.1wherecurrentofcur;

endloop;

commit;

exception

whenothersthen

dbms_output.put_line(sqlerrm);

end;

/

3.REF CURSOR(Cursor Variables)

REF Cursor在運行的時候才能確定遊標使用的查詢。利用REF CURSOR,可以在程序間傳遞結果集(壹個程序裏打開遊標變量,在另外的程序裏處理數據)。

也可以利用REF CURSOR實現BULK SQL,提高SQL性能。

REF CURSOR分兩種,Strong REF CURSOR 和 Weak REF CURSOR。

Strong REF CURSOR:指定retrun type,CURSOR變量的類型必須和return type壹致。

Weak REF CURSOR:不指定return type,能和任何類型的CURSOR變量匹配。

Ref cursor的使用:

1) Type [Cursor type name] is ref cursor

2) Open cursor for...

3) Fetch [Cursor name]

4) Close Cursor

例如:

Step1:

createorreplacepackageTESTas

typeemployees_refcursor_typeisrefcursorreturnemployees%rowtype;

procedureemployees_loop(employees_curINemployees_refcursor_type);

endTEST;

/

Step2:

createorreplacepackagebodyTESTas

procedureemployees_loop(employees_curINemployees_refcursor_type)is

empemployees%rowtype;

begin

loop

fetchemployees_curintoemp;

exitwhenemployees_cur%NOTFOUND;

dbms_output.put_line(emp.employee_id);

endloop;

endemployees_loop;

endTEST;

/

Step3:

setserveroutputon

declare

empRefCurTEST.employees_refcursor_type;

begin

foriin10..20loop

dbms_output.put_line('DepartmentID='||i);

openempRefCurforselect*fromemployeeswheredepartment_id=i;

TEST.employees_loop(empRefCur);

endloop;

exception

whenothersthen

dbms_output.put_line(sqlerrm);

closeempRefCur;

end;

/

4.BULK SQL

使用FORALL和BULK COLLECT子句。利用BULK SQL可以減少PLSQL Engine和SQL Engine之間的通信開銷,提高性能。

1. To speed up INSERT, UPDATE, and DELETE statements, enclose the SQL statement within a PL/SQL FORALL statement instead of a loop construct. 加速INSERT, UPDATE, DELETE語句的執行,也就是用FORALL語句來替代循環語句。

2. To speed up SELECT statements, include the BULK COLLECT INTO clause in the SELECT statement instead of using INTO. 加速SELECT,用BULK COLLECT INTO 來替代INTO。

SQL>createtableemployees_tmpasselectfirst_name,last_name,salaryfromemployeeswhere0=1;

setserveroutputon

declare

cursoremployees_cur(depIdemployees.department_id%type)isselectfirst_name,last_name,salaryfromemployeeswheredepartment_id=depId;

typeemployee_table_typeistableofemployees_cur%rowtypeindexbypls_integer;

employee_tableemployee_table_type;

begin

openemployees_cur(100);

fetchemployees_curbulkcollectintoemployee_table;

closeemployees_cur;

foriin1..employee_table.countloop

dbms_output.put_line(employee_table(i).first_name||''||employee_table(i).last_name||','||employee_table(i).salary);

endloop;

foralliinemployee_table.first..employee_table.last

insertintoemployees_tmpvalues(employee_table(i).first_name,employee_table(i).last_name,employee_table(i).salary);

commit;

end;

/

  • 上一篇:《哈利波特》桃金娘怎麽死的?
  • 下一篇:qq華夏遊戲個性網名
  • copyright 2024編程學習大全網