Oracleカーソルには、表示カーソル、暗黙カーソル、参照カーソルの3種類があります。
フェッチ...バルク収集に
selectステートメントはすべての結果セットをユーザーに返し、結果セットのデータの各行に対して個別の操作を実行することはできません。したがって、カーソルはこの問題を解決できます。
暗黙カーソルは、DML SQLステートメントが実行されるときにOracleによって自動的に作成され、名前はsqlとして固定されます。
表示カーソルはユーザーが作成します
REFカーソル:REFカーソルは、実行時に決定できる動的SQLクエリの結果を処理するために使用されます。
1つの暗黙カーソル
暗黙カーソルに含まれる属性は次のとおりです。
%FOUND:SQLステートメントが1つ以上の行に影響を与える場合はTrue
%NOTFOUND:SQLステートメントがどの行にも影響を与えない場合はTrue
%ROWCOUNT:SQLステートメントの影響を受ける行数
%ISOPEN:カーソルが開いているかどうか
新しいテーブル:
declare
sql_command varchar2(500);
isExsit number ;
begin
select count(1) into isExsit from user_tables where table_name ='SALARY_TBL';
if isExsit <> 0 then
sql_command :='truncate table salary_tbl';
execute immediate sql_command;
sql_command :='drop table salary_tbl';
execute immediate sql_command;
end if;
sql_command := '
create table salary_tbl(
employer_nm varchar(20) ,
department varchar(20) not null,
salary number not null,
leader_nm varchar(20)
)';
execute immediate sql_command;
for i in 1..13000
loop
insert into salary_tbl values('雇佣者'||i,'部门'||Mod(i,50),100+sqrt(i),'雇佣者'||Mod(i,20));
if Mod(i,1000)=0 then
commit;
end if;
end loop;
commit;
end;
/
--隐式游标示例
begin
update salary_tbl set DEPARTMENT ='部门3' where DEPARTMENT ='部门3';
if sql%found then
dbms_output.put_line('修改了'||sql%ROWCOUNT||'行');
end if;
rollback;
end;
/
2、カーソルを表示します
まず、カーソルを定義してからカーソルを開く必要があります。次に、カーソルが特定の結果セットを指します。このとき、1行ずつ読み取り、読み取ったらカーソルを閉じます。
カーソルcurname(パラメーターセット) はSQLstatementです。
----把领导者的薪资变成99999----
declare
sal salary_tbl.employer_nm%type;
cursor mycur is select distinct LEADER_NM from salary_tbl ;
begin
open mycur;
fetch mycur into sal;
while mycur%found loop
update salary_tbl set salary=99999 where employer_nm = sal;
fetch mycur into sal;
end loop;
close mycur;
end;
/
パラメータを渡すための表示カーソルの例:
----把除了部门9的领导者的薪资变成8888----
declare
sal salary_tbl.employer_nm%type;
cursor mycur(depnum number) is select distinct LEADER_NM from salary_tbl where
employer_nm in (select distinct LEADER_NM from salary_tbl)and department <>'部门'||depnum;
begin
open mycur(9);
fetch mycur into sal;
while mycur%found loop
update salary_tbl set salary=8888 where employer_nm = sal;
fetch mycur into sal;
end loop;
close mycur;
end;
/
上記は、カーソルを使用してクエリを実行するためのものです。カーソルを使用して、操作を更新および削除することもできます。
カーソルcurname(パラメーターセット) は、更新用のSQLステートメントです。
カーネームの現在
----把除了部门8的领导者薪资变成7777----
declare
sal salary_tbl%rowtype;
cursor mycur(depnum number) is select * from salary_tbl where
employer_nm in (select distinct LEADER_NM from salary_tbl)and department <>'部门'||depnum for update;
begin
open mycur(8);
fetch mycur into sal;
while mycur%found loop
update salary_tbl set salary=7777 where current of mycur;
fetch mycur into sal;
end loop;
close mycur;
end;
/
ループカーソルはクエリにのみ使用できますが、コードが大幅に簡素化されます。
----把除了部门7的领导者薪资变成6666----
declare
sal salary_tbl%rowtype;
cursor mycur(depnum number) is select * from salary_tbl where
employer_nm in (select distinct LEADER_NM from salary_tbl)and department <>'部门'||depnum for update;
begin
for c1 in mycur(7) loop
update salary_tbl set salary=6666 where current of mycur;
end loop;
end;
/
演習:カーソルを使用してテーブルを初期化し、新しい部門テーブルを作成します(部門番号、総従業員給与、リーダーシップ)
declare
sql_command varchar2(500);
isExsit number ;
cursor dep_cur is select department,sum(salary) as allsalary from salary_tbl group by department;
depdata dep_cur%rowtype;
begin
select count(1) into isExsit from user_tables where table_name ='DEPARTMENT_TBL';
if isExsit <> 0 then
sql_command :='truncate table DEPARTMENT_TBL';
execute immediate sql_command;
sql_command :='drop table DEPARTMENT_TBL';
execute immediate sql_command;
end if;
sql_command := '
create table DEPARTMENT_TBL(
department varchar(20) not null,
all_salary number not null,
leaders varchar(100)
)';
execute immediate sql_command;
open dep_cur;
fetch dep_cur into depdata;
while dep_cur%found loop
insert into DEPARTMENT_TBL(department,all_salary) values(depdata.department,depdata.allsalary);
fetch dep_cur into depdata;
commit;
end loop;
close dep_cur;
end;
/
3、カーソルを参照してください
参照カーソルは、カーソルの定義を直接決定できない場合に使用できます。
定义:TYPEの 型名は、 REF CURSOR IS。
typename refcursorname ;
割り当て:OPEN refcursorname FOR のSQLStatement。
例:DEPARTMENT_TBL.leadersを初期化して、部門の下にあるすべてのリーダーを取得します。;
---初始化部门中的leader----
declare
cursor cur is select distinct department from salary_tbl ; --所有的部门
leadernm DEPARTMENT_TBL.LEADERS%type; --某个部门下的所有领导者,待赋值
type refcursor is ref cursor;
refcur refcursor; --参照游标
refdata salary_tbl.leader_nm%type; --某个部门下的某个领导者,待赋值
begin
for curdata in cur loop
--遍历部门集cur,确定部门curdata下的所有领导者集合
open refcur for select distinct leader_nm from salary_tbl where department=curdata.department;
leadernm :='';
fetch refcur into refdata;
while refcur%found loop
--遍历领导者集合,字符串拼接
if leadernm is null then
leadernm := leadernm ||refdata;
else
leadernm := leadernm ||','||refdata;
end if;
fetch refcur into refdata;
end loop; ---/refcur
dbms_output.put_line(curdata.department || ' '||leadernm);
update DEPARTMENT_TBL set LEADERS=leadernm where department=curdata.department;
end loop; --/cur
--commit;
close refcur;
end;
/
新しいテーブルの結果は次のとおりです。