程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 數據庫知識 >> Oracle數據庫 >> Oracle教程 >> OraclePL/SQL高級編程

OraclePL/SQL高級編程

編輯:Oracle教程

1、 復合數據類型——記錄類型

? 語法格式

type 類型名 is record (

字段1 字段1類型 [not null]:=表達式1;

字段2 字段2類型 [not null] :=表達式2;

… )

? 說明:記錄之間相互賦值要求兩個記錄類型完全相同。

? 案例

舉例1

--創建表並插入記錄

create table student(idnumber, name varchar2(20), birthday date);

insert into studentvalues(100, 'xiaoming', to_date('2000.12.17', 'yyyy.mm.dd'));

insert into studentvalues(200, 'xiaohua', to_date('2001.12.17', 'yyyy.mm.dd'));

insert into studentvalues(300, 'xiaoli', to_date('2002.12.17', 'yyyy.mm.dd'));

--定義記錄類型

Declare

type t_studentRecord isrecord(

id number,

name varchar2(20),

birthday date);

或者:

type t_StudentRecord isrecord(

idstudent.id%type,

name student.name%type,

birthday student birthday%type);

v_students t_StudentRecord;

begin

select * into v_students from students whereid=200;

dbms_output.put_line(v_students.id||' '||v_students.name||' '||to_char(v_students.birthday,'yyyy-mm-dd'));

end;

舉例2

declare

type t_StudentRecord is record(

id number(4),

name varchar2(20),

birthday date);

v_students t_StudentRecord;

v_students_copy t_StudentRecord;

begin

v_students.id:=400;

v_students.name:='趙偉';

v_students.birthday:= to_date('2003.12.17','yyyy.mm.dd');

v_students_copy:=v_students;

dbms_output.put_line(v_students_copy.id||''||v_students_copy.name||' '|| to_char(v_students_copy. birthday, 'yyyy-mm-dd'));

end;

舉例3

declare

type t_StudentRecord is record(

id number(4),

name varchar2(20),

birthday date);

type t_StudentRecord2 is record(

id number(4),

namevarchar2(20),

birthday date);

v_students t_studentRecord;

v_students_copy t_studentRecord2;

begin

v_students.id:=400;

v_students.name:='趙偉';

v_students.birthday:= to_date('2003.12.17','yyyy.mm.dd');;

v_students_copy:=v_students;

dbms_output.put_line(v_students_copy.id||''||v_students_copy.name||' '|| to_char(v_students_copy. birthday, 'yyyy-mm-dd'));

end;

出錯說明:如果兩個記錄類型類型名不同,但是內容完全相同,兩個類型對應的兩個變量不能互相賦值。

2、 集合數據類型——index-by表

? 介紹:類似於普通程序設計語言中的數組概念。

? 聲明index-by表的方法:

Type 類型名 IS TABLE OF typeINDEX BY BINARY_INTEGER;

說明:其中type定義的是index-by表中各元素的類型,可以是內置類型、用戶定義的對象類型或者使用%rowtype的表達式等。

? index-by表中單個元素

在聲明了類型和變量後,可以通過:變量名(index)使用表中的單個元素,其中index是指表中的第幾個元素。

? Index by表的屬性函數

屬性名稱

數據類型

說 明

count

number

返回表中的行數

delete

用於從表中刪除指定(由傳入參數指定)的一行數據

exists

boolean

如果指定的行存在則返回true,否則返回false

first

binary_integer

返回表中第一行的下標

last

binary_integer

返回表中最後一行的下標

next

binary_integer

返回指定行(由傳入參數指定)的下一行的下標

prior

binary_integer

在指定行(由傳入參數指定)的上一行的下標

? 案例

舉例1

declare

type t_StudentRecord isrecord(

idstudent.id%type,

name student.name%type,

birthdaystudent birthday%type);

type t_studentTable is table oft_StudentRecord index by binary_integer;

v_students t_studentTable;

begin:

select * into v_students(100) from student whereid=100;

dbms_output.put_line(v_students(100).id||''||v_students(100).name||' '|| to_char(v_students(100). birthday, 'yyyy-mm-dd'));

end;

舉例2

declare

type t_studentTable is table of student%rowtypeindex by binary_integer;

v_students t_studentTable;

begin

select * into v_students(1) from student whereid=200;

dbms_output.put_line(v_students(1).id ||''||v_students(1).name||'

'|| to_char(v_students(1). birthday,'yyyy-mm-dd'));

end;

舉例3

Declare

Type t_s is table of scott.emp%rowtype Indexby binary_integer;

V_s t_s;

V_index binary_integer;--索引號

V_loop binary_integer;--循環次數

Begin

Select * into v_s(10) from scott.emp whereempno='7788';

Select * into v_s(22) fromscott.emp where empno='7902';

Select * into v_s(-12) fromscott.emp where empno='7934';

V_index:= v_s.first;

V_loop:=v_s.count;

Loop

Dbms_output.put_line(v_s(v_index).empno);

V_index:=v_s.next(v_index);

V_loop:=v_loop-1;

Exit when v_loop<=0;

End loop;

V_index:=v_s.last;

v_s.delete(v_index);

V_index:= v_s.first;

V_loop:=v_s.count;

Loop

Dbms_output.put_line(v_s(v_index).empno);

V_index:=v_s.next(v_index);

V_loop:=v_loop-1;

Exit when v_loop<=0;

End loop;

End;

3、 集合數據類型——變長數組

? 介紹:變長數組:是一個存儲有序元素的集合,每個元素都有一個索引,該索引相對應元素在數組中的位置。變長數組存在大小的限制,但是可以動態進行更改。

? 創建變長數組語句:

? 案例

--創建一個變長數組

Create Type varray_phone as varray(3) of varchar2(50);

  --創建一個人員表,表中人員擁有一列電話(可能有1、2或3個電話號碼)。

  create table person3

  (

  id integer constraintperson3_pk primary key,

  first_name varchar(20),

  last_name varchar(20),

  phone varray_phone

  )

  --填充變長數組

  insert into person3values(1,'yuan','weixiang',varray_phone('12345','34567','56789'));

  select * from person3;

insert intoperson3 values(2,'hao','lihai',varray_phone());

select * from person3;

--修改變長數組中的元素

  update person3 setphone= varray_phone('12345','34567') where id = 2;

  select * from person3;

  --修改變長數組的元素的長度大小

  Alter type varray_phone modifyelement type varchar2(49) cascade --報錯

Alter type varray_phone modify element type varchar2(60)cascade

  說明:cascade選項把更改傳播到數據庫中的依賴對象 Person3就是依賴對象

--修改變長數組元素的數目

alter type varray_phonemodify limit 2 cascade -- 報錯,varray限制只能增大

alter type varray_phonemodify limit 5 cascade

insert into person3 values(3,'yuan','weixiang',varray_phone('12345','34567','56789','34567','56789'));

4、 游標

? 介紹:在PL/SQL程序設計中,有時需要對查詢返回結果集進行逐行處理,這就需要將該查詢返回結果集緩存到一個內存區中,為了能對返回的結果集進行逐行操作,需返回該內存區的首地址,這個地址被稱為游標。

? 定義游標語法

Cursor 游標名 is select語句;

注意:在游標定義中的select語句不能包含into子句。

? 游標屬性

游標屬性

描 述

游標名%isopen

布爾值,如果游標已打開,取值為true,否則為false。

游標名%notfound

布爾值,如果最近一次fetch操作沒有返回結果,則取值為true,否則為false。

游標名%found

布爾值,如果最近一次fetch操作沒有返回結果,則取值為false,否則為true。

游標名%rowcount

數字型值,值為到當前為止返回的行數。

? 案例

舉例1

DECLARE

v_no scott.emp.empno%type;

v_name scott.emp.ename%type;

CURSORc_e IS SELECT empno, ename FROM scott.emp;

BEGIN

OPEN c_e;

LOOP

FETCH c_e INTO v_no, v_name;

EXIT WHEN c_e%NOTFOUND;

Dbms_output.put_lint(v_no||' '||v_name);

END LOOP;

CLOSE c_e;

END;

舉例2

DECLARE

CURSOR c_e IS SELECT empno, ename FROM scott.emp;

BEGIN

For c1 in c_e loop

Dbms_output.put_lint(c1.empno||' '||c1.ename);

END LOOP;

END;

5、 可更新的游標

? 介紹:從游標中抽取數據,可以對數據庫中的數據進行update和delete操作。

? 語法:在定義游標時,必須加for update of子句;在update和delete語句中加上where current of子句。

? 案例

舉例1:對scott方案emp表中某部門的各員工,如果其工資小於1600元,則將其工資設為1600元。

Accept p_deptno prompt‘please enter the deptno’;

--Accept類似與c語言中的scanf,意為從屏幕接受輸入到p_deptno變量中。

declare

v_deptno scott.emp.deptno%type:=&p_deptno;

cursor emp_cursor is select empno,job,sal from scott.emp wheredeptno=v_deptno for update of sal;

begin

for emp_record in emp_cursor loop

if emp_record.sal<1600 then

update emp set sal=1600 where currentof emp_cursor;

end if;

end loop;

end;

舉例2:為職工漲工資,對員工按工資從低到高排序,從工資低的員工開始漲,每位員工漲10%。但要控制員工總工資在50萬之內,一旦總額超過50萬,就停止對剩余的員工漲工資。

6、 帶參數的游標

? 介紹:定義顯示游標時,可以加入參數的定義。在使用游標時,對於參數輸入不同的數值,則游標緩存中的數據也隨之變化。

? 定義游標語法:

cursor 游標名(參數1 數據類型, ….) is select 子句;

? 打開游標語法:

open游標名(&參數1, ….) ;

? 案例:從scott方案的emp表中查詢並打印某個部門的雇員情況,其中部門號由用戶交互式輸入。

Accept v_deptnoprompt‘please enter the deptno;

declare

v_ename scott.emp.ename%type;

v_sal scott.emp.sal%type;

cursor emp_cursor (v_deptno number) is selectename,sal from scott.emp where deptno=v_deptno;

begin

open emp_cursor(&p_deptno);

loop

fetch emp_cursor into v_ename,v_sal;

exit when emp_cursor%notfound;

dbms_output.put_line(v_ename|| ' '||v_sal);

end loop;

close emp_cursor;

end;

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved