程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 數據庫知識 >> Oracle數據庫 >> Oracle教程 >> 學習筆記_oracle——游標與動態SQL

學習筆記_oracle——游標與動態SQL

編輯:Oracle教程

游標
查詢結果及記錄不足,很難用變量表示
游標可以按行訪問結果集
基本原理
DML的結果放在緩沖區
游標是指向這個緩沖區的指針
分類
靜態游標
定義是在編譯時綁定了一個select語句
隱式游標 oracle自動生成的游標
顯示游標 用戶手動申明和操作
動態游標
在運行時游標綁定查詢語句
強類型 只支持與之類型匹配的查詢語句
弱類型 只支持任何查詢語句

顯式游標
使用步驟
1、聲明游標
在聲明(DECLAR)中
CURSOR 游標名 IS <SELECT語句> ;
2、打開游標
OPEN <游標名>;
3、提取游標
FETCH <游標名> INTO <變量列表>
--變量類型、順序、數量相同,每次調用移動一次
4、關閉游標
CLOSE <游標名>
游標的屬性(用游標名%屬性名調用)
%ISOPEN 判斷是否打開
%FOUND 是否有指向效行
%NOTFOUND 是否有指向效行
%ROWCONUT 游標提取過的行數
使用循環游標簡化游標的讀取
FOR <類型> IN <游標名> LOOP
--數據庫操作
END LOOP
其中<類型>是用戶的自定義類型,
系統自動生成,與查詢結果中一致

隱式游標
在PL/SQL中使用SELECT操作即是隱式游標
特點 1、不用聲明
2、不用打開和關閉
3、必須使用INTO字句,結果只能一條
屬性的使用,在數屬性前加上SQL
其中 %ROWCONUT、%FOUND常用來判斷是否為空
在commit之前使用
例如 update .....
IF SQL%ROWCOUNT = 1 THEN
--表已更新
ELSE
--表未更新
END IF;

動態游標
REF動態游標,用於處理多行的查詢結果集,在
打開游標是才確定類型
特點: 1、動態游標可以與不同的語句關聯
2、打開游標是綁定、是REF類型
3、常用在存儲過程中
使用過程
定義游標
TYPE <類型名> IS REF COUSER
RETURN <返回類型名>
聲明游標
<游標名> <類型名>
打開動態游標
OPEN <游標名> FOR <查詢語句>
//=================實例=================
DECLARE
TYPE refcur IS REF COUSOR
RETURN employees%ROWTYPE
v_emp employees%ROWTYPE
BEGIN
OPEN refcur FOR
--SQL語句
LOOP
FETCH refcur INTO v_emp;
EXIT WHEN refcur%NOTFOUND;
--執行語句
END LOOP
CLOSE refcur
END

強類型和弱類型的區別
強類型:帶有RETURN語句
在OPEN時必須是指定的類型的select語句
弱類型:不帶有RETURN語句
在OPEN時可以是任意的select語句

動態SQL
靜態SQL
1、編譯時確定,一般只能使用DML和事務控制語句
2、DDL,回話控制語句不能直接使用
動態SQL
1、不編譯,執行時動態確定
2、根據用戶輸入參數等確定SQL
3、解決PL/SQL中不支持DDL的問題
語法
EXECUTE IMMEDIATE '語句'

EXECUTE IMMEDIATE '語句'
[INTO <變量序列>] --用於接收SQL的查詢結果
[USING <參數序列>] --用於動態接收參數
//============實例================
EXECUTE IMMEDIATE 'CREATE TABLE bonus (id NUMBER, amt NUMBER)'

DECLARE
sql_stmt VARCHAR2(200)
emp_id NUMBER(10) := XX;
emp_rec enployees%ROWTYPE;
BEGIN
sql_stmt := 'select * from employees where id = :id'
EXECUTE IMMEDIATE sql_stmt INTO emp_rec USING emp_id;
END;
[注]只能執行返回結果為一行或者沒有的語句
當返回多行時需要使用REF游標
OPEN <游標> FOR <SQL語句>
[USING <參數列表>]
SQL行列轉換
靜態語句
SELECT t_name 姓名,
sum(CASE t_sourse WHEN '語文' THEN t_score ELSE 0 END) 語文,
sum(CASE t_sourse WHEN '數學' THEN t_score ELSE 0 END) 數學,
sum(CASE t_sourse WHEN '物理' THEN t_score ELSE 0 END) 物理,
FORM td
GROUP BY t_name;

動態語句
DECLARE
t_name VARCHAR(10);
t_coures1 NUMBER;
t_coures2 NUMBER;
t_coures3 NUMBER;
TYPR c_type IS REF CURSOR;
cur c_type;
BEGIN
OPEN cur FOR
'sum (case t_course when ''' || ' 語文' || ''' then t_score else 0 end ) ,
sum (case t_course when ''' || ' 數學' || ''' then t_score else 0 end ) ,
sum (case t_course when ''' || ' 物理' || ''' then t_score else 0 end )
FROM td GROUP BY t_name'
LOOP
FETCH cur INTO t_name,t_course1,t_course2,t_course3
EXIT WHEN cur%NOTFOUND;
END LOOP;
CLOSE cur;
END;

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved