日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

oracle中的cursor属性有哪些,Cursor语法及理解

發(fā)布時(shí)間:2024/8/5 编程问答 42 豆豆
生活随笔 收集整理的這篇文章主要介紹了 oracle中的cursor属性有哪些,Cursor语法及理解 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

游標(biāo)的兩種概念

共享游標(biāo)

:

是用戶提交

SQL

PL/SQL

程序塊到

Oracle

share pool

之后,在

library cache

中生成的一個(gè)可執(zhí)行對(duì)象,這個(gè)對(duì)象我們稱之為游標(biāo)(

cursor

)。是

SQL

語(yǔ)句在進(jìn)行硬解析時(shí)生成的,其元數(shù)據(jù)被在視圖

V$sqlarea

v$sql

中具體化。

PL/SQL

游標(biāo)

:

則是用于存放

SQL

語(yǔ)句的執(zhí)行結(jié)果

,

用戶可以通過(guò)這個(gè)中間緩沖區(qū)

逐條

取出游標(biāo)中的記錄并對(duì)其處理,直到所有的游標(biāo)記錄被逐一處理完畢。需要聲明、打開、提取、關(guān)閉。

共享游標(biāo)包括父游標(biāo)和子游標(biāo)。

父游標(biāo):

是在進(jìn)行硬解析時(shí)產(chǎn)生的。將

SQL

語(yǔ)句的文本進(jìn)行哈希得到哈希值并在

library cache

尋找相同的哈希值(

SQL

語(yǔ)句必須完全一致包括大小寫、空格回車等才能共享

),如不存在則生存父游標(biāo)且保存在

library cache

中,按順序完成后續(xù)步驟。如果此時(shí)存在父游標(biāo),則進(jìn)一步判斷是否存在子游標(biāo)。若存在相同的子游標(biāo),則直接調(diào)用其子游標(biāo)的執(zhí)行計(jì)劃執(zhí)行該

SQL

語(yǔ)句,否則轉(zhuǎn)到下一步進(jìn)行邏輯優(yōu)化。

子游標(biāo):

在發(fā)生硬解析時(shí),在產(chǎn)生父游標(biāo)的同時(shí),則跟隨父游標(biāo)會(huì)產(chǎn)生相應(yīng)的子游標(biāo),此時(shí)

V$SQL.CHILD_NUMBER

的值為

。如果存在父游標(biāo),由于不同的運(yùn)行環(huán)境,此時(shí)同樣會(huì)產(chǎn)生新的子游標(biāo),新子游標(biāo)的

CHILD_NUMBER

在已有子游標(biāo)基礎(chǔ)上以

1

為單位累計(jì)。

v$sql

中的每一行表示了一個(gè)

child cursor

子游標(biāo)

,根據(jù)

sql_id

與父

cursor

關(guān)聯(lián)。

child cursor

有自己的

address

,即

v$sql.child_address

如果你想確定是由那種原因造成的子游標(biāo),需要查看

v$sql_shared_cursor

1.

父游標(biāo)的關(guān)鍵信息是

sql

文本,子游標(biāo)的關(guān)鍵信息是執(zhí)行計(jì)劃和執(zhí)行環(huán)境。

2.

硬解析通常是由于不可共享的父游標(biāo)造成的,如經(jīng)常變動(dòng)的

SQL

語(yǔ)句,或動(dòng)態(tài)

SQL

或未使用綁定變量等。解決硬解析的辦法則通常是使用綁定變量來(lái)解決。

3.

與父游標(biāo)

SQL

文本完全一致的情形下,多個(gè)相同的

SQL

語(yǔ)句可以共享一個(gè)父游標(biāo)。

4.SQL

文本、執(zhí)行環(huán)境完全一致的情形下,子游標(biāo)能夠被共享,否則如果執(zhí)行環(huán)境不一致則生成新的子游標(biāo)。如果

SQL

文本相同,但是可能提交

SQL

語(yǔ)句的用戶不同,或者用戶提交的

SQL

語(yǔ)句所涉及到的對(duì)象為同名詞等,都有可能生成不同的子游標(biāo)。因?yàn)檫@些

SQL

語(yǔ)句的文本雖然完全一樣,但是上下文環(huán)境卻不一樣,因此這樣的

SQL

語(yǔ)句不是一個(gè)可執(zhí)行的對(duì)象,必須細(xì)化為多個(gè)子游標(biāo)后才能夠執(zhí)行。

5.

游標(biāo)是可以被所有進(jìn)程共享的,也就是說(shuō)如果

100

個(gè)進(jìn)程都執(zhí)行相同的

SQL

語(yǔ)句,那么這

100

個(gè)進(jìn)程都可以同時(shí)使用該

SQL

語(yǔ)句所產(chǎn)生的游標(biāo),從而節(jié)省了內(nèi)存。

這里討論的游標(biāo)是指

pl/sql

語(yǔ)句中定義的游標(biāo)(

session cursor

)

Oracle

PL

/

SQL

中當(dāng)查詢返回結(jié)果超過(guò)一行時(shí),從中每次指向一條記錄進(jìn)行交互的話,就需要用到游標(biāo)。

例如:

SELECT

INTO

查詢語(yǔ)句,一次只能從數(shù)據(jù)庫(kù)中

select

一行數(shù)據(jù)來(lái)進(jìn)行

insert

,但是如果要處理多行數(shù)據(jù),就要由程序員定義一個(gè)顯式游標(biāo),并通過(guò)與游標(biāo)有關(guān)的語(yǔ)句進(jìn)行處理。

說(shuō)明:

select

* into new_table from table;

sqlserver

中正常,但

oracle

會(huì)報(bào)錯(cuò),

oracle

里面

select...into...

pl/sql

的變量賦值語(yǔ)句

例如:

select

count(*) into v_count from table_name where id=1;

意思就是把

id=1

的數(shù)量放到一變量

v_count

當(dāng)然

insert into ?new_table? select * from table

都是在

sqlserver

oracle

中都是正常的,都可以一條

insert

語(yǔ)句插入多行數(shù)據(jù)

個(gè)人一般使用

for

m in (select * from emp)loop

來(lái)替代顯式游標(biāo)的功能

顯式游標(biāo)

(需要明確定義

cursor

,即有定義

cursor

的就是顯示游標(biāo))

fetch

游標(biāo)則必須用到顯式游標(biāo),需要

open

close

顯式游標(biāo)語(yǔ)法如下

declare

cursor mycursor1 is select * from emp;

--

聲明游標(biāo)

table_row mycursor1%rowtype;

--mycursor1%rowtype

表示數(shù)據(jù)類型是一行數(shù)據(jù)

xx number;

begin

open mycursor1;

--

打開游標(biāo)

loop

fetch mycursor1 into table_row;

--

取出游標(biāo)結(jié)果放入變量

table_row

exit when mycursor1%notfound;

xx:=table_row.empno;

insert into emp_2 (empno,ename,job ) values (xx,table_row.ename,table_row.job);

end loop;

commit;

close mycursor1;

--

關(guān)閉游標(biāo)

end;

如下顯式游標(biāo)

fetch

游標(biāo)名

into

變量

,

變量

,

變量,且變量不需要再定義為游標(biāo)名

%rowtype,

但是

sql

出現(xiàn)

游標(biāo)名

.

字段

則會(huì)報(bào)錯(cuò)

PLS-00225:

subprogram or cursor

'MYCURSOR111' reference is out of scope

declare

cursor mycursor111 is select empno,ename,job from emp;

--

聲明游標(biāo)

xx number;

yy varchar2(10);

zz varchar2(10);

begin

open mycursor111;

--

打開游標(biāo)

loop

fetch mycursor111 into xx,yy,zz;

--

取出游標(biāo)結(jié)果放入變量

xx,yy,zz

exit when mycursor111%notfound;

insert into emp_2 (empno,ename,job ) values (xx,yy,zz);

end loop;

commit;

close mycursor111;

--

關(guān)閉游標(biāo)

end;

顯示游標(biāo)

fetch

的注意事項(xiàng)

1.

游標(biāo)對(duì)應(yīng)的不管是一個(gè)還是多個(gè)字段,

fetch

游標(biāo)名

.

字段

into

變量,會(huì)報(bào)錯(cuò)

PLS-00225: subprogram or cursor

'MYCURSOR111' reference is out of scope

,但是可以出現(xiàn)

fetch

游標(biāo)名

into

字段

1

對(duì)應(yīng)的變量

1,

字段

2

對(duì)應(yīng)的變量

2,

字段

3

對(duì)應(yīng)的變量

3

,這里這些變量可以不需要定義為

%rowtype

,如果定義為

%rowtype

,則只能

into

一個(gè)

%rowtype

的變量,

fetch

游標(biāo)名

into

游標(biāo)名

%rowtype

2.

游標(biāo)對(duì)應(yīng)多個(gè)字段時(shí),

Fetch

游標(biāo)名

into

變量時(shí),其實(shí)是按順序把字段一個(gè)個(gè)

into

到變量的,如果游標(biāo)對(duì)應(yīng)的字段有

3

個(gè),但是

into

的變量只有

2

個(gè),則報(bào)錯(cuò)

PLS-00394:

wrong number of values in the INTO list of a FETCH statement

3.

游標(biāo)必須

open

,否則會(huì)報(bào)錯(cuò)

ORA-01001:

無(wú)效的游標(biāo)

,當(dāng)然如果沒有

close

的話執(zhí)行過(guò)程中不會(huì)報(bào)錯(cuò),但是游標(biāo)會(huì)一直存儲(chǔ)在

PAG

中,直到

session

關(guān)閉才會(huì)釋放,所以如果很多顯式都不關(guān)閉會(huì)導(dǎo)致

PGA

很大。

游標(biāo)

FOR

循環(huán)確實(shí)很好的簡(jiǎn)化了游標(biāo)的開發(fā),我們不在需要

open

fetch

close

語(yǔ)句,不在需要用

%FOUND

屬性檢測(cè)是否到最后一條記錄,這一切

Oracle

隱式的幫我們完成了。

(雖然是顯式游標(biāo),不過(guò)個(gè)人覺得更像隱式游標(biāo))

declare cursor mycursor1 is select * from emp;

--

聲明

cursor

vv varchar2(200);

begin

--open mycursor1;

--

這里

open

游標(biāo)反倒會(huì)報(bào)錯(cuò)

for m in mycursor1 loop

--m

不需要聲明

vv:=m.empno;

insert into emp_2 (empno,ename,job ) values (vv,m.ename,m.job);

end loop;

commit;

--close mycursor1;

--

這里

close

游標(biāo)反倒會(huì)報(bào)錯(cuò)

end;

下面語(yǔ)句只是比上面語(yǔ)句多了一行

xx

mycursor11%rowtype

,發(fā)現(xiàn)不需要這一行也一樣。

declare cursor mycursor11 is select * from emp;

--

聲明

cursor

xx mycursor11%rowtype;

yy varchar2(100);

begin

--open mycursor11;??????????????????????????????????? --

這里

open

游標(biāo)反倒會(huì)報(bào)錯(cuò)

for xx in mycursor11 loop

--m

不需要聲明

yy:=xx.empno;

insert into emp_2 (empno,ename,job ) values (yy,xx.ename,xx.job);

end loop;

commit;

--close mycursor11;???????????????????????????????? --

這里

close

游標(biāo)反倒會(huì)報(bào)錯(cuò)

end;

簡(jiǎn)單的

for

循環(huán)連

cursor

都不用聲明了,此時(shí)

m

不需要聲明類型,這是隱式游標(biāo)

create table emp_2 as select * from emp where 1=2

declare vv varchar2(200);

begin

for m in (select * from emp)loop

vv:=m.empno;

insert into emp_2 (empno,ename,job ) values (vv,m.ename,m.job);

end loop;

commit;

end;

相比如上,以下加了

sql%found

sql%rowcount

可以說(shuō)明是隱式游標(biāo)

declare vv varchar2(200);

begin

for m in (select * from emp) loop

if

sql%found

then

dbms_output.put_line(

sql%rowcount

);

end if;

vv:=m.empno;

insert into emp_2 (empno,ename,job ) values (vv,m.ename,m.job);

end loop;

commit;

end;

隱式游標(biāo)

DECLARE

hid

VARCHAR2

(

10

);

hname

varchar

(

20

);

BEGIN

SELECT

empno

,

ename

INTO

hid

,

hname

FROM

emp_2

;

IF

SQL

%

FOUND

then

dbms_output.put_line

(

hid

||

'

的名字是

'

||

hname

);

end

if;

END;

則如下報(bào)錯(cuò),

select

into

只能有一行結(jié)果,加上

where

條件限定在一行后就不會(huì)報(bào)錯(cuò)了

ORA-01422:

實(shí)際返回的行數(shù)超出請(qǐng)求的行數(shù)

ORA-06512:

line 5

顯式游標(biāo)的個(gè)屬性

cursor_name%ISOPEN

游標(biāo)是否打開

cursor_name%FOUND

最近的

FETCH

是否提取到數(shù)據(jù)

cursor_name%NOTFOUND

最近的

FETCH

是否沒有提取到數(shù)據(jù)

cursor_name%ROWCOUNT

返回到目前為止,已經(jīng)從游標(biāo)緩沖區(qū)中提取到數(shù)據(jù)的行數(shù)

隱式游標(biāo)的屬性

SQL%ROWCOUNT

代表

DML

語(yǔ)句成功執(zhí)行的數(shù)據(jù)行數(shù)

SQL%FOUND

值為

TRUE

代表插入、刪除、更新或單行查詢操作成功

SQL%NOTFOUND

SQL%FOUND

屬性返回值相反

SQL%ISOPEN???????????? ???DML

執(zhí)行過(guò)程中為真,結(jié)束后為假

begin

for m in (select sign_id,SIGN_INFO_ID from MDS_SIGN_LIST)

loop

insert into MDS_SIGN_LIST_v2 (SIGN_ID,SIGN_INFO_ID )

values (m.sign_id,m.SIGN_INFO_ID);

end loop;

end;

與50位技術(shù)專家面對(duì)面20年技術(shù)見證,附贈(zèng)技術(shù)全景圖

總結(jié)

以上是生活随笔為你收集整理的oracle中的cursor属性有哪些,Cursor语法及理解的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。