Oracleの原則:カーソル、表示カーソル、暗黙カーソル、参照カーソル

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;
/



新しいテーブルの結果は次のとおりです。

おすすめ

転載: blog.csdn.net/superSmart_Dong/article/details/107027864