oracle ora-01001,ORA-01001 and ORACLE游标
為了處理sql語句,Oracle必須分配一片內(nèi)存區(qū)域——上下文區(qū)域(context area),它包含了完成該處理所必需的信息, 其中包括語句要處理行的數(shù)目、 一個(gè)指向語句被分析以后產(chǎn)生的表示形式的指針, 以及查詢的活動(dòng)集(active set 即查詢返回的行的集合)。
游標(biāo)(cursor)是一個(gè)指向上下文區(qū)的句柄(handle)或指針。 通過游標(biāo), pl/sql程序可以控制上下文區(qū)和處理語句時(shí)上下文區(qū)發(fā)生什么
事情。
靜態(tài)游標(biāo), 顯式游標(biāo)和隱式游標(biāo)
顯式游標(biāo)的處理包括四個(gè)pl/sql步驟,如下:
1)聲明游標(biāo)。
2)為查詢打開游標(biāo)。
3)將結(jié)果提取(fetch)到pl/sql變量中。
4)關(guān)閉游標(biāo)。
游標(biāo)聲明
對游標(biāo)的聲明定義了游標(biāo)的名字并將該游標(biāo)和一個(gè)SELECT語句相關(guān)聯(lián)。
語法是:
CURSOR cursor_name IS SELECT_statement;
任何的SELECT 語句都是合法的,包括連接(join)和帶有UNION或MINUS子句的語句,但是不能包含INTO子句,游標(biāo)的聲明可以在WHERE子句中引用pl/sql變量。這些變量被認(rèn)為是聯(lián)編變量(bind variable,即已經(jīng)被分配空間并映射到絕對地址的變量)
游標(biāo)打開
當(dāng)打開一個(gè)游標(biāo)時(shí)會(huì)發(fā)生下面的事情:
a.聯(lián)編變量的取值被檢查。
b.根據(jù)聯(lián)編變量的取值,活動(dòng)集被確定。
c.活動(dòng)集的指針指向第一行。
在游標(biāo)打開時(shí)刻并且僅僅在游標(biāo)打開時(shí)刻對聯(lián)編變量進(jìn)行檢查。
游標(biāo)的屬性
在pl/sql中可以使用游標(biāo)的四個(gè)屬性。pl/sql塊中,游標(biāo)屬性附加在游標(biāo)名的后邊。游標(biāo)屬性返回的不是類型(如%type,%rowtype),它返回的是在表達(dá)式中可以使用的數(shù)值。這些屬性是%FOUND、%NOTFOUND、%ISOPEN、%ROWCOUNT。
a.%FOUND是一個(gè)布爾屬性。如果前一個(gè)FETCH語句返一個(gè)行,那么它的返回TRUE, 否則FALSE。如果在未打開游標(biāo)以前就設(shè)置了%FOUND,那么回返回ora-1001(無效得游標(biāo))。
b.%NOTFOUND的行為方式與%FOUND正好相反。
c.%ISOPEN也是布爾屬性,用來確定相關(guān)的游標(biāo)是否被打開了。
d.%ROWCOUNT此數(shù)字屬性返回目前為止由游標(biāo)返回行的數(shù)目。如果在相關(guān)聯(lián)的游標(biāo)還沒有打開或者已經(jīng)關(guān)閉的時(shí)候進(jìn)行引用,那么
也會(huì)返回ora-1001錯(cuò)誤。
處理隱式游標(biāo)
顯式游標(biāo)用來處理返回多于一行的SELECT語句,但是所有的SQL語句在上下文區(qū)內(nèi)部是可執(zhí)行的,因此都有一個(gè)游標(biāo)指向此上下文區(qū)。此游標(biāo)就是所謂的“SQL 游標(biāo)”(SQL cursor)。 與顯式游標(biāo)不同的是, SQL游標(biāo)不被程序打開和關(guān)閉。 pl/sql隱含地打開SQL游標(biāo),處理其中的SQL語句,然后關(guān)閉該游標(biāo)。
隱式游標(biāo)用于處理INSERT、UPDATE、DELETE和單行的SELECT..INTO語句。因?yàn)镾QL 游標(biāo)是通過pl/sql 引擎打開和關(guān)閉的,所以O(shè)PEN、FETCH、CLOSE命令是無關(guān)的。但是游標(biāo)屬性(用SQL%..)可以被應(yīng)用于SQL游標(biāo)。
Ref:
eg:
CREATE OR REPLACE PROCEDURE OSM_DML_2SP.OSM_TAB_PROCPROC2(
ival IN OSM_TAB_PROC.COL_0%TYPE:=10,
ocnt IN OUT NUMBER)
AS
a OSM_TAB_PROC.COL_0%TYPE;
r OSM_TAB_PROC%ROWTYPE;
i NUMBER := 0;
CURSOR c1(ct0 NUMBER) IS SELECT COL_0 FROM OSM_DML_2SP.OSM_TAB_PROC WHERE COL_0>ct0;
BEGIN
IF c1%ISOPEN = FALSE THEN
OPEN c1(60);
END IF;
LOOP
EXIT WHEN c1%NOTFOUND; -- if cursor is not open used it ORA-01001 error
FETCH c1 INTO a;
SELECT * INTO r FROM OSM_DML_2SP.OSM_TAB_PROC WHERE COL_0=a AND ROWNUM<2;
r.COL_0 := a + ival;
r.COL_3 := TO_CHAR(a) || TO_CHAR(SYSDATE);
INSERT INTO OSM_DML_2SP.OSM_TAB_PROC VALUES r;
i := i + 1;
END LOOP;
CLOSE c1;
ocnt := i;
END;
DECLARE
cnt NUMBER := 0;
BEGIN
FOR i IN 1 .. 3 LOOP
OSM_DML_2SP.OSM_TAB_PROCPROC2(236*i,cnt);
EXECUTE IMMEDIATE 'INSERT INTO OSM_DML_2SP.OSM_TAB_PROC(COL_0) VALUES(:1)' USING cnt*i;
END LOOP;
END;
閱讀(6788) | 評論(0) | 轉(zhuǎn)發(fā)(0) |
總結(jié)
以上是生活随笔為你收集整理的oracle ora-01001,ORA-01001 and ORACLE游标的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: oracle随机备选数,Oracle查询
- 下一篇: oracle 10g gateway 安