Oracle PL/SQL編程之變量


注:

以下測試案例所用的表均來自與scott方案,使用前,請確保該用戶解鎖.

1、簡介

和大多數編程語言一樣,在編寫PL/SQL程序時,可以定義常量和變量,在pl/sql程序中包括有:

a、標量類型(Scalar)

b、復合類型(Composite)

c、參照類型(Refrence)

d、lob(large object)類型

下面來一一介紹

 

2、標量(Scalar)類型       只能存放單個值的變量

在編寫pl/sql語句時,如果需要用到變量,那么就需要在定義部分定義變量。pl/sql中定義變量個常量的語法如下:

identifier [constant] datatype [not null] [:=| default expr]

identifier:名稱

constant:指定常量,需要指定它的初始值,且其值是不能改變的

datatype:數據類型

not null:指定變量值不能為空

:=給變量或者常量指定初始值

defalut:用於指定初試值

expr:指定初始值的pl/sql表達式,可是文本值、其他變量或者函數

 

2.1、標量定義的案例

定義一個變長字符串

v_name varchar2(10);

定義一個小數  范圍   -9999.99~9999.99

v_sal number(6,2)

定義一個小數,並給定初始值6.6  注:     :=是pl/sql的變量賦值號

v_num number(6.2):=6.6

定義一個日期類型的數據

v_date date;

定一個布爾變量,不能為空,初始值為false;

v_bool boolean not null defalut false;

注:pl/sql中使用標量並給其賦初值的方式不同於其他的編程語言,需要在等號前加":"

 

2.2、標量使用的案例  

作用:變量是存放pl/sql塊中最普通的變量

輸入一個員工號,顯示雇員的姓名、工資、個人所得稅(稅率為0.03),代碼如下:

declare
c_tax_rate number(3,2):=0.03;
v_name varchar2(5);
v_sal number(7,2);
v_tax_sal number(7,2);
begin
select ename,sal into v_name,v_sal from emp where empno=&no;
v_tax_sal:=v_sal * c_tax_rate;
dbms_output.put_line('姓名是:'||v_name||'工資:'||v_sal||'交稅:'||v_tax_sal);
end;

ok,輸出成功!

但是上面的代碼存在漏洞

我們給變量指定了定長,但是如果我們輸入的編號對應的ename的長度大於5,就像下面這樣:

我輸入了7654,這時對應的ename的長度大於5,所以程序包錯了

所以必須解決這個問題,當我們不知道變量長度的時候,讓其長度和對應的表字段匹配,從而使程序不抱錯,解決方案參考2.3

 

2.3、標量中使用%type

declare
c_tax_rate number(3,2):=0.03;
v_name emp.ename%type;
v_sal emp.sal%type;
v_tax_sal emp.sal%type;
begin
select ename,sal into v_name,v_sal from emp where empno=&no;
v_tax_sal:=v_sal * c_tax_rate;
dbms_output.put_line('姓名是:'||v_name||'工資:'||v_sal||'交稅:'||v_tax_sal);
end;

ok,再次輸入7654,正常輸出。

 

3、復合變量(composite)   用於存放多個值的變量

 

3.1、復合類型-pl/sql記錄

類似高級語言中的結構體,需要注意的是,當引用pl/sql記錄中的成員時,必須要加記錄變量作為前綴(記錄變量.記錄成員),如果定義一個pl/sql記錄類型呢?代碼如下:

declare
type emp_record_type is record(
name emp.ename%type,
salary emp.sal%type
);

這樣就定義了一個名為emp_record_type的復雜變量類型,那么如何使用這個類型呢?代碼如下:

sp_record emp_record_type;

ok,這樣就定義了一個emp_record_type類型的變量,名為sp_record;

declare
type emp_record_type is record(
name emp.ename%type,
salary emp.sal%type
);
sp_record emp_record_type;
begin
select ename,sal into sp_record from emp where empno=7788;
dbms_output.put_line('員工名:'|| sp_record.name||'工資:'||sp_record.salary);
end;

ok,使用復合類型-pl/sql記錄成功的輸出了員工名和工資

 

3.2、復合類型-pl/sql表

這種類型相當於高級語言的數組,但需要注意的是高級語言中的數組下標不能為負數,而pl/sql可以是可以為負數,而且表元素的下標沒有限制。如何定義一個pl/sql表類型呢?代碼如下:

declare
type sp_table_type is table of emp.ename%type index by binary_integer;

ok,上面的代碼定義了一個類型為emp.ename的pl/sql表類型,也可以理解為類型為emp.ename的數組,那么如何使用這個類型,代碼如下:

sp_table sp_table_type

ok,這樣就定義了一個emp_table_type類型的變量,名為sp_table;

declare
type sp_table_type is table of emp.ename%type index by binary_integer;
sp_table sp_table_type;
begin
  select ename into sp_table(0) from emp where emp.empno=7788;
  dbms_output.put_line('姓名是:'||sp_table(0));
  end;

ok,上面的代碼將empno為7788的員工姓名放入了sp_table中,並指定其下標為0,所以我們在下面輸出時,指定輸出sp_table(0),所以正常輸出,

下面是使用pl/sql表類型經常出錯的地方:

i、但是當我們指定存放的下標為-1,而輸出的下標為0時,代碼就會報錯,具體的代碼如下:

declare
type sp_table_type is table of emp.ename%type index by binary_integer;
sp_table sp_table_type;
begin
  select ename into sp_table(-1) from emp where emp.empno=7788;
  dbms_output.put_line('姓名是:'||sp_table(0));
  end;
  

所以當我們使用pl/sql表類型時,需要注意下標的對應

 

ii、當查詢返回的結果集是多個,但是又指定pl/sql表類型的下標,相當於pl/sql表類型只接受一個值,這個時候會報錯,具體代碼如下:

declare
type sp_table_type is table of emp.ename%type index by binary_integer;
sp_table sp_table_type;
begin
  select ename into sp_table(-1) from emp;
  dbms_output.put_line('姓名是:'||sp_table(-1));
  end;
  

select ename from emp,返回了多個結果,而into sp_table(-1)只接受一個值,所以報上面的錯誤了。

 

4、參照變量

參照變量是指用於存放數值指針的變量,通過使用參照變量,可以使應用程序共享相同對象,從而降低占用的空間。在編寫pl/sql程序時,可以使用游標變量(ref cursor)和對象類型變量

(ref obj_type)兩種參照變量類型。

4.1、參照變量-ref cursor游標變量

使用游標時,當定義游標時,不需要指定相應的select 語句,但是當使用游標時,就需要指定select語句,這樣一個游標就和一個selec語句結合了.下面是游標的案例

a、請使用pl/sql編寫一個塊,可以輸入部門號,顯示該部門下所有員工的姓名和工資,代碼如下:

首先定義一個游標類型:

type sp_emp_cursor is ref cursor;

接着定義一個sp_emp_cursor游標類型的游標變量

test_cursor sp_emp_cursor;

然后打開游標,將游標與結果集結合

open test_cursor for select ename,sal from emp where empno=&no;

ok,現在test_cursor指向了select ename,sal from emp where empno=&no   結果集

然后循環游標,取出我們想要的數據,然后賦值給定義好的標量,並輸出給標量,循環完畢(游標使用完畢),關閉游標,代碼如下:

declare
type sp_emp_cursor is ref cursor;--定義一個游標類型
test_cursor sp_emp_cursor;--定義一個游標變量
v_ename emp.ename%type;
v_sal emp.sal%type;
begin
  --執行
  --把test_cursor和一個select結合
  open test_cursor for select ename,sal from emp where deptno=&no;
  --循環取出
  loop
    fetch test_cursor into v_ename,v_sal;
    --判斷test_cursor是否循環到空數據,如果循環到空數據,那么就停止循環
    exit when test_cursor%notfound;
    dbms_output.put_line('姓名:'||v_ename||'工資:'||v_sal);
   end loop;
   
   --使用完畢關閉游標
   close test_cursor;
end;
  

ok,完成a需求。

 

b、在a的基礎上,如果某個員工的工資低於200元,就增加100元。使用游標完成需求。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM