oracle游標

?游標(cursor )是一個私有的SQL工作區域,是一個指向上下文區的句柄或指針,位于內存中的 "臨時表"

?游標是SQL的一個內存工作區,由系統或用戶以變量的形式定義。游標的作用就是用于臨時存儲從數據庫中提取的數據塊。在某些情況下,需要把數據從存放在磁盤的表中調到計算機內存中進行處理,最后將處理結果顯示出來或最終寫回數據庫。這樣數據處理的速度才會提高,否則頻繁的磁盤數據交換會降低效率

游標用來管理從數據源返回的數據的屬性(結果集)。這些屬性包括并發管理、在結果集中的位置、返回的行數,以及是否能夠在結果集中向前和/或向后移動(可滾動性)。

游標跟蹤結果集中的位置,并允許對結果集逐行執行多個操作,在這個過程中可能返回至原始表,也可能不返回至原始表

?

原理游標是從數據表中提取出來的數據,以?臨時表?的形式存放到?內存中,在游標中有一個?數據指針,?在初始狀態下指向的是首記錄,利用?fetch?語句可以移動該指針,從而對游標中的數據進行各種操作,然后將操作結果寫回到數據庫中。
作用

1、用來查詢數據庫,獲取記錄集合(結果集)的指針,可以讓開發者基于當前的結果集位置檢索一行或連續的幾行在每 ? ? 條結果集上作操作,以編 程的方式訪問數據。
2、用 ‘犧牲內存’ 來提升 SQL 執行效率,適用于?大數據處理

3.在結果集的當前位置修改行中的數據,對其他用戶所做的數據更改定義不同的敏感性級別。

?

程序語言是面向記錄的,一組變量一次只能存放一個變量或者一條記錄,無法直接接收數據庫中的查詢結果集引入游標就解決了這個問題

標的類型

REF 游標用于處理運行時才能確定的動態 SQL 查詢的結果

隱式游標不易被用戶和程序員察覺和意識到,實際上Oracle服務器使用隱式游標來解析和執行我們提交的SQL 語句;而顯式游標是程序員在程序中顯式聲明的;通常我們說的游標均指顯式游標

隱式

游標

在 PL/SQL 中使用?DML 和 select into時,會自動創建隱式游標,隱式游標自動聲明、打開和關閉(無法手動查看),其名為?SQL,通過檢查隱式游標的屬性可以獲得?最近執行的 DML 和 select into 語句的信息

DML操作和單行SELECT語句會使用隱式游標,它們是:?
* 插入操作:INSERT。?
* 更新操作:UPDATE。?
* 刪除操作:DELETE。?
* 單行查詢操作:SELECT ... INTO ...。

當系統使用一個隱式游標時,可以通過隱式游標的屬性來了解操作的狀態和結果,進而控制程序的流程。隱式游標可以使用名字SQL來訪問,但要注意,通過SQL游標名總是只能訪問前一個DML操作或單行SELECT操作的游標屬性。所以通常在剛剛執行完操作之后,立即使用SQL游標名來訪問屬性

%FOUND語句影響了一行或多行時為 TRUE,前一個 fetch 語句是否有值,true:有,false:沒有
%NOTFOUND

語句沒有影響任何行時為TRUE,與上述相反,常被用于?退出循環,true:有,false:沒有, null : 空。注意哦,只有 為 true 時,才退出(當 第一次 fetch 為 null 時,不會退出!)

EXIT WHEN SQL%NOTFOUND OR SQL%NOTFOUND IS NULL;

%ROWCOUNT語句影響的行數,當前成功執行的數據行數(非總記錄數
%ISOPEN游標是否打開,始終為FALSE
SQL> DECLAREv_TOYID TOYS.ID%type := '&TOYID';v_TOYNAME TOYS.NAME%Type := '&TOYNAME';BEGINUPDATE TOYS SET NAME = v_TOYNAMEWHERE toyid=v_TOYID;IF SQL%NOTFOUND THENDBMS_OUTPUT.PUT_LINE('編號未找到。');ELSEDBMS_OUTPUT.PUT_LINE(‘表已更新');END IF;END;
DECLAREv_RoomData   rooms%ROWTYPE;
BEGINSELECT *INTO v_RoomData FROM rooms WHERE room_id = -1;IF SQL%NOTFOUND THEN 
/*注意,這里不執行,以上自動引發select into預定義異常*/INSERT INTO temp_table (char_col) VALUES 
('Not found!');END IF;
EXCEPTIONWHEN NO_DATA_FOUND THEN
/*注意,這是真正執行的*/INSERT INTO temp_table (char_col)VALUES ('Not found, exception handler');
END;
declare2    v_rows number;3  begin4    update emp5    set comm=10006    where deptno=30;7   v_rows:=SQL%ROWCOUNT;8   dbms_output.put_line('給部門30的' 
|| v_rows || '個雇員每人加了1000元獎金');9  end;

?

顯式游標

顯式游標在 PL/SQL 塊的聲明部分定義查詢,該查詢可以返回多行

1、一行一行的處理返回的數據。

2、保持當前處理行的一個跟蹤,像一個指針一樣指示當前的處理的記錄。

3、允許程序員在PLSQL塊中人為的控制游標的開啟、關閉、上下移動

聲明游標

劃分存儲區域,注意此時并沒有執行Select?語句

?

CURSOR 游標名[(參數1 數據類型[,參數2 數據類型...])]?
IS SELECT語句;?
參數是可選部分,所定義的參數可以出現在SELECT語句的WHERE子句中。如果定義了參數,則必須在打開游標時傳遞相應的實際參數。?
SELECT語句是對表或視圖的查詢語句,甚至也可以是聯合查詢。可以帶WHERE條件、ORDER BY或GROUP BY等子句,但不能使用INTO子句。在SELECT語句中可以使用在定義游標之前定義的變量。?

打開游標

執行Select?語句,獲得結果集存儲到游標中,此時游標指向結果集頭, 而不是第一條記錄

在可執行部分,按以下格式打開游標:?
OPEN 游標名[(實際參數1[,實際參數2...])];?
打開游標時,SELECT語句的查詢結果就被傳送到了游標工作區。

結果集控制

移動游標取一條記錄

在可執行部分,按以下格式將游標工作區中的數據取到變量中。提取操作必須在打開游標之后進行。?
FETCH 游標名 INTO 變量名1[,變量名2...];?
或?
FETCH 游標名 INTO 記錄變量;?
游標打開后有一個指針指向數據區,FETCH語句一次返回指針所指的一行數據,要返回多行需重復執行,可以使用循環語句來實現。控制循環可以通過判斷游標的屬性來進行。?
下面對這兩種格式進行說明:?
第一種格式中的變量名是用來從游標中接收數據的變量,需要事先定義。變量的個數和類型應與SELECT語句中的字段變量的個數和類型一致。?
第二種格式一次將一行數據取到記錄變量中,需要使用%ROWTYPE事先定義記錄變量,這種形式使用起來比較方便,不必分別定義和使用多個變量。?
定義記錄變量的方法如下:?
變量名 表名|游標名%ROWTYPE;?
其中的表必須存在,游標名也必須先定義。

關閉游標

顯式游標打開后,必須顯式地關閉。游標一旦關閉,游標占用的資源就被釋放,游標變成無效,必須重新打開才能使用。

SQL>DECLAREmy_toy_price toys.toyprice%TYPE;				  聲明游標CURSOR toy_cur ISSELECT toyprice FROM toysWHERE toyprice<250;BEGINOPEN toy_cur;  LOOPFETCH toy_cur INTO my_toy_price;EXIT WHEN toy_cur%NOTFOUND;DBMS_OUTPUT.PUT_LINE ('TOYPRICE=:玩具單價=:'||my_toy_price);END LOOP;CLOSE toy_cur;END;

帶參數的

DECLAREdesig    VARCHAR2(20);emp_code VARCHAR2(5);empnm    VARCHAR2(20);CURSOR emp_cur(desigparam VARCHAR2) ISSELECT empno, ename FROM employeeWHERE designation=desig;BEGINdesig:= '&desig';OPEN emp_cur(desig);LOOPFETCH emp_cur INTO emp_code,empnm;EXIT WHEN emp_cur%NOTFOUND;DBMS_OUTPUT.PUT_LINE(emp_code||' '||empnm);END LOOP;CLOSE emp_cur;END

?允許使用游標刪除或更新活動集中的行
聲明游標時必須使用 SELECT … FOR UPDATE語句

所有返回集中的數據行都將處于行級(ROW-LEVEL)獨占式鎖定,其他對象只能查詢這些數據行,

??不能進行UPDATE、DELETE或SELECT...FOR UPDATE操作。

???在多表查詢中,使用OF子句來鎖定特定的表,如果忽略了OF子句,那么所有表中選擇的數據行都將被鎖定。

???如果這些數據行已經被其他會話鎖定,那么正常情況下ORACLE將等待,直到數據行解鎖

SQL> SET SERVEROUTPUT ON
SQL> DECLAREnew_price NUMBER;CURSOR cur_toy ISSELECT toyprice FROM toys WHERE toyprice<100FOR UPDATE OF toyprice;
BEGINOPEN cur_toy;LOOPFETCH cur_toy INTO new_price;EXIT WHEN cur_toy%NOTFOUND;UPDATE toysSET toyprice = 1.1*new_priceWHERE CURRENT OF cur_toy;END LOOP;CLOSE cur_toy;COMMIT;
END;
declare2   cursor mycur(dept_no integer) is3   select * from dept4   where deptno>dept_no for update;5  begin6    for myreco in mycur(50) loop7     delete from dept8      where current of mycur;9    end loop;10  end;

循環游標

declare2   cursor c_dept is3   select deptno, dname from dept order by deptno;4   cursor c_emp(p_dept varchar2) is5    select ename,sal from emp where deptno=p_dept order by ename;6    v_salary emp.sal%type;7  begin8     for r_dept in c_dept loop9       dbms_output.put_line('Department:' || r_dept.deptno||'-'||r_dept.dname);10     v_salary:=0;11     for r_emp in c_emp(r_dept.deptno) loop12      dbms_output.put_line('Name:'|| r_emp.ename||' salary='||r_emp.sal);13       v_salary:=v_salary+r_emp.sal;14      end loop;15      dbms_output.put_line('total salary for dept:'|| v_salary);16     end loop;17* end;

?

動態SELECT

Oracle支持動態SELECT語句和動態游標,動態的方法大大擴展了程序設計的能力。?
對于查詢結果為一行的SELECT語句,可以用動態生成查詢語句字符串的方法,在程序執行階段臨時地生成并執行,語法是:?
execute immediate 查詢語句字符串 into 變量1[,變量2...];?

SET SERVEROUTPUT ON   DECLARE   str varchar2(100);  v_ename varchar2(10);  begin  str:='select ename from scott.emp where empno=7788';  execute immediate str into v_ename;   dbms_output.put_line(v_ename);  END;   

?

REF

游標

在變量聲明部分定義的游標是靜態的,不能在程序運行過程中修改。雖然可以通過參數傳遞來取得不同的數據,但還是有很大的局限性。通過采用動態游標,可以在程序運行階段隨時生成一個查詢語句作為游標。要使用動態游標需要先定義一個游標類型,然后聲明一個游標變量,游標對應的查詢語句可以在程序的執行過程中動態地說明。

?

REF 游標和游標變量用于處理運行時動態執行的 SQL 查詢
創建游標變量需要兩個步驟:
聲明 REF 游標類型
聲明 REF 游標類型的變量

TYPE <ref_cursor_name> IS REF CURSOR
[RETURN <return_type>];

聲明強類型的 REF 游標

1、for 后是?SQL語句(而不能是 字符串)
2、cur… 必須和 return 的?類型完全一致
3、無法使用?綁定變量

TYPE my_curtype IS REF CURSORRETURN stud_det%ROWTYPE;
order_cur my_curtype; 

聲明弱類型的 REF 游標,系統類型 SYS_REFCURSOR

TYPE my_ctype IS REF CURSOR;
stud_cur my_ctype;
declare2    type cursor_type  is ref cursor;3    stu_cursor cursor_type;4    v_stu 學生表%rowtype;5  begin6    open stu_cursor for7      select * from 學生表 where 性別='男';8    loop9      fetch  stu_cursor into v_stu;10      exit when stu_cursor%notfound;11     dbms_output.put_line(v_stu.學號 ||' '||v_stu.姓名||' '||v_stu.性別||' '||v_stu.年齡);12    end loop;13   close stu_cursor;14  end;
declare2  type emp_type is ref cursor;3  cur emp_type;4  name varchar2(20);5  salary number(7,2);6  begin7    open cur for 'select ename,sal from emp where job=:1'8    using 'SALESMAN';9   loop10     fetch cur into name,salary;11     exit when cur%notfound;12    dbms_output.put_line(name||':'||salary);13   end loop;14   close cur;15  end;
 declare2   type empcurtyp is ref cursor;3   type idlist is table of emp.empno%type;4   type namelist is table of emp.ename%type;5   type sallist is table of emp.sal%type;6   emp_cv empcurtyp;7   ids idlist;8   names namelist;  sals sallist;9   row_cn number;10  begin11    open emp_cv for select empno,ename,sal from emp;12    fetch emp_cv bulk collect into ids,names,sals;13   close emp_cv;14   for i in ids.first.. ids.last loop15     dbms_output.put_line(ids(i)||' '||names(i)||' '||sals(i));16   end loop;17* end;

?

游標變量的優點和限制

游標變量的功能強大,可以簡化數據處理。
游標變量的優點有:
可從不同的 SELECT 語句中提取結果集
可以作為過程的參數進行傳遞
可以引用游標的所有屬性
可以進行賦值運算
使用游標變量的限制:
不能在程序包中聲明游標變量
FOR UPDATE子句不能與游標變量一起使用
不能使用比較運算符

DECLAREv_sql VARCHAR(2000);v_b1 NUMBER(3) := 3;TYPE record_stu IS RECORD(v_id system.stu.s_id%TYPE,v_xm system.stu.s_xm%TYPE);TYPE table_stu IS TABLE OF record_stu;v_stu table_stu;cur_stu SYS_REFCURSOR;
BEGINv_sql := 'SELECT t.s_id, t.s_xm FROM stu t WHERE t.s_id <= :b1';OPEN cur_stu FOR v_sqlUSING v_b1; -- 綁定變量 : 大數據處理常用優化手段LOOPFETCH cur_stu BULK COLLECTINTO v_stu LIMIT 1; -- 數據量太少,僅當前測試使用哦,實際開發 建議 500 左右EXIT WHEN v_stu.count = 0;FOR i IN v_stu.first .. v_stu.last LOOPdbms_output.put_line('序號:' || v_stu(i).v_id || ' , ' || '姓名:' || v_stu(i).v_xm);END LOOP;END LOOP;CLOSE cur_stu;EXCEPTIONWHEN OTHERS THENdbms_output.put_line(SQLCODE || ' : ' || SQLERRM);dbms_output.put_line(dbms_utility.format_error_backtrace);
END;

?

%type、%rowtype、record
  • %type:單條?記錄類型自動匹配
  • %rowtype:所有?記錄類型自動匹配
  • record:部分?記錄類型自動匹配,該變量類型允許用戶在代碼中使用“表”,以便存儲多個行數據。記錄表類型是對記錄類型的擴展,可以處理多個記錄或多行數據
集合操作

在 Oracle 中集合中,若想擴充大小有兩種方法
方式1:(手動)集合.extend(一次只申請一個空間長度)
方式2:(自動)Type <Type_name> IS TABLE OF <data_type> index by ..
Oracle 下標定義和其他語言有些區別
下標從 1 開始算,而不是 0 哦。

varry 一維數組(設置長度)

type 數組名 is varray(size) of 元素類型 [not null];

size : 數組最大長度,必填項。

DECLARE
? ?TYPE varry IS VARRAY(4) OF VARCHAR2(30); -- 最大長度是 4
? ?v_varry varry;
BEGIN
? ?-- 初始化 3 個下標, 也就只能寫 3 個長度,即使定義的 有 4 個長度
? ?v_varry ?:= varry('a', 'b', 'c'); -- 構造方法 進行初始化

? ?FOR i IN v_varry.first .. v_varry.last LOOP
? ? ? dbms_output.put_line(v_varry (i));
? ?END LOOP;

END;
/

table 多維數組

type table_name is table of element_type[not null]
[index by [binary_integer|pls_integer]];

index by : 創建一個主鍵索引,以便引用記錄表變量中的特定行.
-- 下列參數下標自增(無需 顯示初始化:extend)
binary_integer : ?由 Oracle來 執行,不會出現溢出,但是執行速度較慢,
? ? ? ? ? ? ? ? ? 因為它是由 Oracle 模擬執行。
pls_integer ? ?: ?由硬件即直接由 CPU 來運算,因而會出現溢出,但其執行速度
? ? ? ? ? ? ? ? ? 較前者快許多,數據范圍:參考 ‘Oracle 官方解釋中的紅色字體’

?存儲單行多列

(效果同 varry 一維數組)

這個和 VARRAY 類似。但是賦值方式稍微有點不同,不能使用同名的 構造函數 進行賦值。
有個細節:去掉 index by .. 后,是可以使用 構造函數

DECLARE
? ?-- 此例中 ?INDEX BY PLS_INTEGER 加不加都可以,具體解釋看后面
? ?TYPE varry_stu IS TABLE OF VARCHAR2(30) INDEX BY PLS_INTEGER;
? ?v_stu_varry varry_stu;
BEGIN

? ?-- varry_stu := varry_stu('a', 'b', 'c');?
? ?-- 此時 不能像 varry 使用上述 構造函數 進行初始化了哦

? ?v_stu_varry(1) := 'a';
? ?v_stu_varry(2) := 'b';
? ?v_stu_varry(3) := 'c';

? ?FOR i IN v_stu_varry.first .. v_stu_varry.last LOOP
? ? ? dbms_output.put_line(i || ' : ' || v_stu_varry(i));
? ?END LOOP;

END;
/

存儲多行多列TYPE <類型名> IS TABLE OF [%rowtype / record]
若想匹配所有字段,與 %rowtype 最為方便
若想匹配部分字段,與 record 最為方便
下列實例是數據倉庫中,表同步 的常見寫法
當然,實現功能的寫法有很多種,這里,只給出我認為最優的。
DECLAREi_stu_id NUMBER(3) := 3; -- 模擬入參 v_sql    VARCHAR(2000);cur_stu  SYS_REFCURSOR;TYPE record_stu IS RECORD(v_id   stu.id%TYPE,v_name stu.name%TYPE);TYPE table_stu IS TABLE OF record_stu; -- 思考:加不加 index by ...?v_stu table_stu;BEGINv_sql := 'SELECT t.id, t.name FROM stu t WHERE t.id <= :b1';OPEN cur_stu FOR v_sqlUSING i_stu_id; -- 綁定變量 : 大數據處理常用優化手段LOOPFETCH cur_stu BULK COLLECTINTO v_stu LIMIT 2; -- 數據量太少,僅當前測試使用哦,實際開發 建議 500 左右EXIT WHEN v_stu.count = 0;-- 細節:如果此處使用 cur_stu%notfound 不足 limit n 的數據不會在操作了哦FOR i IN v_stu.first .. v_stu.last LOOPdbms_output.put_line('學號:' || v_stu(i).v_id || ' , ' || '姓名:' || v_stu(i).v_name);-- 模擬表同步(不存在時 insert、存在時 update)END LOOP;END LOOP;CLOSE cur_stu;EXCEPTIONWHEN OTHERS THENIF cur_stu%ISOPEN THENCLOSE cur_stu;END IF;dbms_output.put_line(SQLERRM);dbms_output.put_line(dbms_utility.format_error_backtrace);
END;
/

?

何時使用 index byPL/SQL 向?集合類型?中插入數據時,必須先擴展?內存空間,有兩種方式
  • 手動:extend()
  • 自動:index by …

?

DECLARETYPE string_array IS TABLE OF VARCHAR2(30);TYPE string_array_index IS TABLE OF VARCHAR2(30) INDEX BY PLS_INTEGER;v_a string_array;v_b string_array_index;
BEGIN-- 不加 INDEX BY... 是 可以 使用構造函數的v_a := string_array('a1', 'a2', 'a3');-- 加了 INDEX BY... 是 不能 使用構造函數的-- varry_stu := varry_stu('b1', 'b2', 'b3'); v_b(v_b.count) := 'b0'; -- 細節: 剛開始,數組為空,故  v_b.count = 0v_b(v_b.count) := 'b1'; -- 之后 count 依次遞增(切記:不可指定 count哦,不然就不遞增了,而是重復修改原記錄)v_b(v_b.count) := 'b2';-- TODO: 分別插入新數據 new1, new2-- v_av_a.extend(2);v_a(4) := 'new1';v_a(5) := 'new2';FOR i IN v_a.first .. v_a.last LOOPdbms_output.put_line(i || ' : ' || v_a(i));END LOOP;dbms_output.new_line();-- v_bv_b(v_b.count) := 'new1';v_b(v_b.count) := 'new2';FOR i IN v_b.first .. v_b.last LOOPdbms_output.put_line(i || ' : ' || v_b(i));END LOOP;
END;
/1 : a1
2 : a2
3 : a3
4 : new1
5 : new20 : b0
1 : b1
2 : b2
3 : new1
4 : new2

?

空數組時
  • 沒加 index by 的數組必須?初始化
  • 空數組時,array.first = array.last = null;
  • 空數組時,array.count = 0;
DECLARETYPE string_array IS TABLE OF VARCHAR2(30);TYPE string_array_index IS TABLE OF VARCHAR2(30) INDEX BY PLS_INTEGER;v_a string_array := string_array(); -- 必須先初始化v_b string_array_index; -- 加了 index by 相當于 默認初始化
BEGINdbms_output.put_line('v_a.first: ' || v_a.first);dbms_output.put_line('v_a.last: ' || v_a.last);dbms_output.put_line('v_a.count: ' || v_a.count);dbms_output.new_line();dbms_output.put_line('v_b.first: ' || v_b.first);dbms_output.put_line('v_b.last: ' || v_b.last);dbms_output.put_line('v_b.count: ' || v_a.count);
END;
/v_a.first: 
v_a.last: 
v_a.count: 0v_b.first: 
v_b.last: 
v_b.count: 0

?

清除數組元素 delete 和 置 null 的區別
  • 置 null:清除數組元素,但?不刪除內存空間
  • delete:清除數組元素,并且?刪除內存空間
DECLARETYPE string_array_index IS TABLE OF VARCHAR2(30) INDEX BY PLS_INTEGER;v_b string_array_index;
BEGINv_b(v_b.count) := 'b1'; -- 因為 數組為空,故而 v_b.count = 0v_b(v_b.count) := 'b2';v_b(v_b.count) := 'b3';-- TODO:置 null 方式,清除數組元素dbms_output.put_line('原數組長度:' || v_b.count);v_b(0) := NULL;dbms_output.put_line('置 null 后的長度:' || v_b.count);FOR i IN v_b.first .. v_b.last LOOPdbms_output.put_line(i || ' : ' || v_b(i));END LOOP;dbms_output.new_line();-- TODO:delete 方式,清除數組元素v_b.delete(0);dbms_output.put_line('delete 后的長度:' || v_b.count);FOR i IN v_b.first .. v_b.last LOOPdbms_output.put_line(i || ' : ' || v_b(i));END LOOP;
END;
/原數組長度:3
置 null 后的長度:3
0 : 
1 : b2
2 : b3delete 后的長度:2
1 : b2
2 : b3

?

數組遍歷時,不連續下標異常

數組遍歷時,是嚴格按照下標順序來的,若中間出現?斷層(找不到下標),就會報錯

DECLARETYPE string_array_index IS TABLE OF VARCHAR2(30) INDEX BY PLS_INTEGER;v_b string_array_index;
BEGINv_b(v_b.count) := 'b1'; -- 因為 數組為空,故而 v_b.count = 0v_b(v_b.count) := 'b2';v_b(v_b.count) := 'b3';v_b.delete(1); -- 刪除 'b2'FOR i IN v_b.first .. v_b.last LOOP-- 測試時,請去掉 IF,直接 dbms_output 即可。IF v_b.exists(i) THENdbms_output.put_line(i || ' : ' || v_b(i));END IF;END LOOP;
END;
/0 : b1
2 : b3

?

?

數組屬性和函數屬性/函數?? ?描述
count?? ?返回集合中元素的個數
delete?? ?刪除集合中 所有 的元素及 extend
delete(x)?? ?刪除元素下標為 x 的元素(對 varry 非法)
delete(x, y)?? ?刪除元素下標從 x 到 y 的元素(對 varry 非法)
trim?? ?從集合末端開始刪除一個元素(對 index by 非法)
trim(x)?? ?從集合末端開始刪除 x 個元素 (對 index by 非法)
exists(x)?? ?如果集合元素 x 已經 初始化(extend) ,則返回 true,否則返回 false
extend?? ?在集合 末尾 添加一個元素(對 index by 非法)
extend(x)?? ?在集合 末尾 添加 x個元素 (對 index by 非法)
extend(x, n)?? ?在集合 末尾 添加元素 x 個下標為n 的 副本(對 index by 非法)
first?? ?返回集合中第一個元素的下標號,對 varry 集合 始終 返回 1(除非 未初始化 則為 空)
last?? ?返回集合中最后一個元素的下標號,對 varry 集合 值始終 等于 count (除非 未初始化 則為 空)
limit?? ?返回 varry 集合的最大的元素個數,對 index by 無效
next(x)?? ?返回在第 x 個元素之后緊挨著它的元素下標(x+1),若 x 是最后一個元素,則返回 null
prior(x)?? ?返回在第x個元素之前緊挨著它的 元素下標(x-1),如果 x 是第一個元素,則返回 null
Cursor與 Ref Cursor區別從技術底層看,兩者是相同的。普通plsql cursor在定義時是“靜態”的。而Ref cursors可以動態打開。
?
Ref cursor根據邏輯動態打開;而游標cursor定義好了就無法修改了
ref cursor可以返回給客戶端,cursor則不行。
cursor可以是全局的global ,ref cursor則必須定義在過程或函數中。
ref cursor可以在子程序間傳遞,cursor則不行。
cursor中定義的靜態sql比ref cursor效率高,所以ref cursor通常
?①靜態游標是靜態定義,REF?游標是動態關聯;

?②使用REF?游標需REF?游標變量。

?③REF?游標能做為參數進行傳遞,而靜態游標是不可能的。

總結游標用于處理查詢結果集中的數據
游標類型有:隱式游標、顯式游標和 REF 游標
隱式游標由 PL/SQL 自動定義、打開和關閉
顯式游標用于處理返回多行的查詢
顯式游標可以刪除和更新活動集中的行
要處理結果集中所有記錄時,可使用循環游標
在聲明 REF 游標時,不需要將 SELECT 語句與 其關聯?

?

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/535497.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/535497.shtml
英文地址,請注明出處:http://en.pswp.cn/news/535497.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

找出占用cpu最高的線程

ps -eo %cpu,pid |sort -n -k1 -r | head -n 1| awk {print $2}| xargs top -b -n1 -Hp | grep COMMAND -A1 |tail -n 1 |awk {print $1}| xargs printf 0x%x ? 在命令行輸入top&#xff0c;然后shiftp查看占用CPU最高的進程&#xff0c;記下進程號 ? 在命令行輸入top -Hp…

系統學習SpringFramework:Spring 概述

本篇內容包括&#xff1a;Spring/SpringFrame 概述、Spring IOC 和 AOP 概述、Spring 全家桶內容概述&#xff08;包括&#xff1a;Spring Boot、Spring Cloud、Spring Cloud data flow …&#xff09;等內容&#xff01; 一、Spring/SpringFrame 概述 Spring 是一個生態體系&…

存儲過程與函數oracle

存儲在數據庫中供所有用戶程序調用的子程序叫做存儲過程&#xff0c;存儲函數。 存儲過程是在大型數據庫系統中&#xff0c;用PL/SQL語言編寫的能完成一定處理功能的存儲在數據庫字典中的程序&#xff0c;它是一個命名的 PL/SQL 塊&#xff0c;經編譯后存儲在數據庫中&#xff…

系統學習SpringFramework:Spring IOC

本篇內容包括&#xff1a;IOC 和 DI 的概念、Spring 容器&#xff0c;即 BenaFactory 與 AplicationConext 等 IOC 相關內容。 一、IOC 和 DI 的概念 1、IOC IoC&#xff08;Inversion of control &#xff09;即“控制反轉”&#xff0c;它是一種設計思想而非一個技術實現。…

徹底卸載oracle

linux刪除Oracle安裝目錄下的所有文件和文件夾即可。windows 1.關閉oracle所有的服務。可以在windows的服務管理器中關閉 2.打開注冊表&#xff1a;regedit 打開路徑&#xff1a; HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\ 刪除該路徑下的所有以oracle開始的服務…

系統學習SpringFramework:Spring AOP

本篇內容包括&#xff1a;Spring AOP 概述&#xff08;AOP 簡介、AOP 為什么叫面向切面編程、AOP 主要用來解決的問題 和 AOP 的相關術語&#xff09;、Spring AOP Demo&#xff08;xml 方式、注解方式&#xff09;以及相關知識點&#xff08;JDK 動態代理和 CGLIB 代理、Sprin…

rowid

ROWID的格式rowidOOOOOOFFFBBBBBBRRR說明數據對象號相對文件號數據塊號行號 上述表格是Oracle 9i及以上版本數據庫中的rowid格式: 6位對象號3位相對文件號6位數據塊號3位行號&#xff0c;是一個18位的64進制值。這個18位的64進制值在數據庫內卻是以10個bytes合計80個bit的二進制…

git和gitlab安裝

1.下載git最新包 https://mirrors.edge.kernel.org/pub/software/scm/git/ 將最新包上傳至服務器/home目錄 tar -Jxvf 解壓 進入git目錄 ./configure --prefix/usr/local/git make make install 錯誤解決&#xff1a;Cant locate ExtUtils/MakeMaker.pm in INC yum i…

系統學習SpringFramework:循環依賴與三級緩存

本篇內容包括&#xff1a;Spring 中的循環依賴問題&#xff08;包括 Spring 中的循環依賴問題和Spring 中的循環依賴的 5 種場景的介紹&#xff09;、Spring 三級緩存介紹、4 個 Spring 無法自動解決的循環以來場景以及其對應的手動解決方式。 一、Spring 中的循環依賴問題 1、…

oracle安裝需要的包列表

redhat7.5安裝圖形界面&#xff1a; [rootwwyt ~]# rpm -ivh --nodeps --force xorg-x11-font* [rootwwyt ~]# mount -o loop -t iso9660 rhel-server-7.5-x86_64-dvd.iso /media/iso/ [rootwwyt ~]# cat /etc/yum.repos.d/my.repo [base] nameredhat7.5 baseurlfile:///m…

深入理解Java虛擬機:Java類的加載機制

本篇內容包括&#xff1a;Java 類的加載機制&#xff08;Jvm 結構組成、Java 類的加載&#xff09;、類的生命周期&#xff08;加載-驗證-準備-解析-初始化-使用-卸載&#xff09;、類加載器 以及 雙親委派模型。 一、Java 類的加載機制 1、 Jvm 結構組成 Jvm 整體組成可分為…

新版谷歌瀏覽器開啟Flash支持

瀏覽器地址欄中輸入chrome://version查看Chrome瀏覽器、Flash插件的版本信息。 Chrome 69.0-70.0版本Chrome 71.0-74.0及以后版本谷歌瀏覽器地址欄中輸入【chrome://flags/#enable-ephemeral-flash-permission】&#xff0c;將【Enable Ephemeral Flash Permissions】從【Defau…

深入理解Java虛擬機:Java垃圾回收機制

本篇內容包括&#xff1a;JAVA 垃圾回收機制概述、有哪些內存需要回收、如何回收&#xff08;標記-清除、標記-整理&#xff08;標記-清除-壓縮&#xff09;、復制&#xff08;標記-復制-清除&#xff09;、分代收集等算法&#xff09; 以及 何時進行垃圾回收等內容&#xff01…

深入理解Java虛擬機:Java垃圾回收器

本篇內容包括&#xff1a;7 種 Jvm 垃圾回收器的介紹、對比 以及 對應的 Jvm 參數設置&#xff0c;這 7 種包括了&#xff1a;Serial、ParNew 以及 Parallel Scavenge 三種新生代回收器 和 &#xff1a;Serial Old、Parallel Old 以及 CMS 三種老年代回收器&#xff0c;此外還有…

oracle跨越千年處理

如果指定的兩位年份0-4950-99 如果當前 的兩位年 份是 0-49返回的日期是當前世紀返回的日期是上個世紀50-99返回的日期是下個世紀返回的日期是當前世紀 current yearSpecified DateRR FormatYY Format199527-OCT-9519951995199527-OCT-171951917200127-OCT-1720012017200127-OC…

網絡協議:什么是網絡分層的七四五

本篇內容包括&#xff1a;網絡分層七層、五層、四層網絡協議概念的介紹&#xff0c;IOS 體系結構的介紹與構成、TCP/IP體系結構的簡介及與IOS體系的關系 以及五層體系結構的介紹。 一、七層、五層、四層網絡協議概念 1、關于網絡協議 網絡協議&#xff0c;即是指計算機網絡中…

查看表空間相關命令

默認表空間數據文件大小根據DATA BLOCKS的大小有關&#xff0c;默認最大為32GB表空間達到32G&#xff0c;只能增加數據文件alter tablespace 表空間名 add datafile 數據文件路徑‘ size 500m autoextend on next 100m maxsize 10000M;未達到32G&#xff0c;修改數據文件的擴展…

網絡協議:一文搞懂Socket套接字

本篇內容包括&#xff1a;Socket 套接字的簡介、Socket 套接字的分類、Java 中的 Socket 即 java.net.ServerSocket、java.net.Socket 的使用&#xff0c;以及Java 使用套接字 Scoket 編程的Demo。 一、Socket 簡介 TCP&#xff08;傳輸控制協議&#xff09;是一種面向連接的、…

RESETLOGS

使用resetlogs選項&#xff0c;會把當前的日志序號&#xff08;log sequence number&#xff09;重設為1&#xff0c;并拋棄所有日志信息。在以下條件時需要使用resetlogs選項&#xff1a; 在不完全恢復&#xff08;介質恢復&#xff09;&#xff1b; 使用備份控制文件。 使…