Oracle 學習開發子程式 游標 引數游標

2021-08-29 22:14:11 字數 4748 閱讀 6213

[b]一、引數游標 [/b]

引數游標是帶有引數的游標,在定義引數游標之後,當使用不同引數值多次開啟游標時,可以產生不同的結果集,語法如下:

cursor cursor_name(parameter_name datatype) is select_statement;

定義引數游標時,游標引數只能指定資料型別,而不能指定長度。

示例如下:

declare

cursor temp_cursor(no number) is select name from cip_temps where id=no;

v_name cip_temps.name%type;

begin

open temp_cursor(1);

loop

fetch temp_cursor into v_name;

exit when temp_cursor%notfound;

dbms_output.put_line(v_name);

end loop;

close temp_cursor;

end;

[b]二、使用游標更新或刪除資料[/b]

通過使用顯示游標,不僅可以一行一行的處理select語句結果,而且也可以更新或刪除當前游標的資料,注意,如果要通過游標更新或刪除資料,在定義游標時一定要帶有for update子句,語法如下:

[color=red]cursor cursor_name(parameter_name datatype) is select_statement for updae [of column_reference][nowait];[/color]如上所示:for update子句用於在游標結果集資料上加行共享鎖,以防止其他使用者在相應行上執行dml操作,當select語句要引用到多張表是,使用of子句可以確定哪些表要加鎖,如果沒有of子句,則會在select語句所引用的全部表上加鎖,nowait用於指定不等待鎖,為了更新或刪除當前游標行資料,必須在update 或delete語句中引用where current of 子句,語法如下:

[color=red]update table_name set column=.. where current of cursor_name;

delete from table_name where current of cursor_name;[/color]

[b]1、使用游標更新資料[/b]

declare

cursor temp_cursor is select name,address,id from cip_temps for update;

v_name cip_temps.name%type;

v_address cip_temps.address%type;

v_id cip_temps.id%type;

begin

open temp_cursor;

loop

fetch temp_cursor into v_name,v_address,v_id;

exit when temp_cursor%notfound;

if(v_id>4) then

update cip_temps set name='name'||to_char(v_id),address='address'||to_char(v_id) where current of temp_cursor;

end if;

end loop;

close temp_cursor;

end;

[b]2、使用游標刪除資料[/b]

declare

cursor temp_cursor is select name,address,id from cip_temps for update;

v_name cip_temps.name%type;

v_address cip_temps.address%type;

v_id cip_temps.id%type;

begin

open temp_cursor;

loop

fetch temp_cursor into v_name,v_address,v_id;

exit when temp_cursor%notfound;

if(v_id>2) then

delete from cip_temps where current of temp_cursor;

end if;

end loop;

close temp_cursor;

end;

[b]3、使用of子句在特定表加行共享鎖。[/b]

如果使用子查詢涉及到多張表,那麼預設情況下會在所有表上加行共享鎖,為了只在特定表上加行共享鎖,需要在for update子句後帶有of子句,of後面跟欄位名,如果跟表名或游標名稱,則會報錯:標示符無效。示例如下:

declare

cursor gdata is select name,address,cip_temps.id from cip_temps,cip_t

where cip_temps.id=cip_t.id for update of address;

rs gdata%rowtype;

begin

open gdata;

loop

fetch gdata into rs;

exit when gdata%notfound;

if rs.id=1 then

delete from cip_temps where current of gdata;

else

update cip_temps set name='塞北的雪' where current of gdata;

end if;

end loop;

close gdata;

end;

[b]4、使用nowait子句[/b]

使用for update語句對被作用於行加鎖,如果其他會話已經在被作用於行上加鎖,那麼預設情況下當前會話要一直等待對方釋放鎖,通過在for update子句中指定 nowait語句,可以避免等待鎖,當指定了nowait子句之後,如果其他會話已經在被作用行加鎖,那麼當前會話會顯示錯誤提示資訊,並退出pl/sql,示例如下:

declare

cursor gdata is select name,address,cip_temps.id from cip_temps,cip_t

where cip_temps.id=cip_t.id for update nowait;

rs gdata%rowtype;

begin

open gdata;

loop

fetch gdata into rs;

exit when gdata%notfound;

if rs.id=1 then

delete from cip_temps where current of gdata;

else

update cip_temps set name='塞北的雪' where current of gdata;

end if;

end loop;

close gdata;

end;

三、游標for迴圈

使用游標for迴圈是迴圈游標最簡單的方法,oracle會隱含開啟游標、迴圈提取資料、關閉游標,語法如下:

for record_name in cursor_name loop

..........

end loop;

如上所示:cursor_name是已經定義的游標名稱,record_name是oracle隱含定義的記錄變數。

1、使用游標for迴圈

當使用游標開發程式時,建議使用for迴圈,從而簡化**程式,示例如下:

declare

cursor temp_cursor is select name,age,address,id from cip_temps;

begin

for emp_record in temp_cursor loop

dbms_output.put_line(temp_cursor%rowcount||'第一行資料:'||emp_record.name||':'|| emp_record.age||':'|| emp_record.address||':'|| emp_record.id);

end loop;

end;

2、在游標for迴圈時直接使用子查詢

declare

begin

for emp_record in (select * from cip_temps) loop

dbms_output.put_line('第一行資料:'||emp_record.name||':'|| emp_record.age||':'|| emp_record.address||':'|| emp_record.id);

end loop;

end;

Oracle 子程式內聯

start 如果子程式 a 呼叫 b,內聯可以把 b 的 合併到 a 中,從而減少子程式呼叫,提高效能,下面是乙個簡單的例子。子程式 a procedure a isbegin 指定下面的子程式 b 內聯 pragma inline b,yes b 1 注意此處的子程式不會內聯 b 2 end a ...

Oracle 內建子程式簡介

大學生兼職支援 url sql set serveroutput on sql remark 內建程式包 sql remark 常用的內建程式包如下 sql remark dbms out pl sql中的輸入和輸出顯示 sql remark dbms job 任務排程服務 sql remark d...

oracle巢狀子程式

劍破冰山學習筆記 巢狀子程式的說明 將乙個子程式定義在乙個pl sql塊中的,該子程式稱為巢狀子程式。只有定義在具名塊中,才能儲存到資料庫中,匿名塊裡是無法儲存到資料庫的 區別 函式和過程是schema級別的子程式,包裡的函式和過程,是package級別的子程式。這兩類都不是巢狀子程式。宣告 巢狀子...