Oracle定義PL/SQL變數

來源:互聯網
上載者:User
Oracle定義PL/SQL變數

 

前言:
使用變數可以儲存電腦需要處理的資料,為了給該變數分配適當的記憶體空間,還需要指定資料類型,有的資料類型還需要指定長度,如字串。
有些類型可以用於建表(如char),有些則不能(如boolean,rowtype)。
同樣是字串,建表時的限制為4000,在指令碼中則為3萬多。

簡單文法:變數名 資料類型;
完整文法:變數名 [constant] 變數類型 [not null] [default 值 | :=值]

其中“[ ]”表示可以不寫,“|”表示任選其一。

下面給出變數定義及解釋,資料類型先用建表時所用的資料類型:
v1 char:
說明:沒有給出長度,所以v1隻能儲存一個字元。超過了則會出錯:數字或值錯誤 : 字串緩衝區太小。

v2 varchar2(10);
說明:v2最多隻能儲存10個字元。如果不寫長度,會出錯:字串長度限制在範圍(1...32767)

v3 number;
說明:v3儲存的數字範圍非常大,幾乎可以認為是沒有限制的。

v4 number(5);
說明:v4最多能夠儲存5位整數。如果有小數,Oracle會自動四捨五入。如果整數部分超過5位,則會報錯:數字或值錯誤 : 數值精度太高。

v5 number(5,2);
說明:v5最多能夠儲存3位整數,2位小數。如果小數位不止2位,則Oracle會自動四捨五入。整數位超過3位會報錯,同上。

v6 date;
說明:可以直接儲存sysdate的值;如果是指定日期,則要用to_date來轉化。否則報錯:文字與格式字串不匹配。

定義了變數,變數的預設值為空白,此時進行計算,結果一定為NULL。所以變數必須初始化。
初始化有三種方式:

v7 constant number := 100;
說明:定義v7為常量,定義時就必須給定值。然後在程式中就不能再對v7進行賦值了,否則會報錯:運算式 'V7' 不能用作賦值目標。

v8 number default 10;
說明:定義v8時就給定預設值10。注意,number類型變數的預設值不是0,而是NULL。

v9 number not null := 1000.50;
說明:定義v9變數不可為空,此時必須給出一個不為NULL的值。在運行時發現v9為NULL,則報錯:說明為 NOT NULL 的變數必須有初始化賦值。

預測各列印結果,如果代碼有錯誤請先改正:
declare
v1 char;
v2 varchar2(10);
v3 number;
v4 number(5);
v5 number(5,2);
v6 date;
v7 number default 10;
begin
v1:='ab';
v2:='abcd';
v4:=9998.99;
v5:=1000.5555555;
v6:=to_date('2002-10-2','yyyy-mm-dd');
dbms_output.put_line(v1);
dbms_output.put_line(v2);
dbms_output.put_line(v3+100);
dbms_output.put_line(v4);
dbms_output.put_line(v5);
dbms_output.put_line(v6);
dbms_output.put_line(v7+100);
end;

只能在指令碼中使用的變數類型:
上面的資料類型,同時在建表時也能使用。而下面的資料類型只能在PL/SQL指令碼中使用。
即:boolean,type,rowtype,record,替代變數、table類型。
其中:
·一個變數只能儲存一個值,叫做“標量變數”。如:char、type。
·一個變數只能儲存多個值,叫做“複合變數”。如:rowtype、record,table。

1、布爾類型 boolean
boolean類型主要表達真或假。可以為boolean類型變數賦值true或false。
主要用於PL/SQL指令碼的流程式控制制。

樣本:
declare
v1 boolean;
begin
v1:=1>2;
dbms_output.put_line(v1);
end;

問題:列印的結果是什麼,是true、false、1、0?
回答:
都不對。運行時得到錯誤資訊:調用 'PUT_LINE' 時參數個數或類型錯誤。
這是因為在指令碼中不能直接列印boolean類型的值,所以只能在指令碼中使用if語句來判斷。

修改樣本:
declare
v1 boolean;
begin
v1:=1>2;
if(v1)then
     dbms_output.put_line('真');
else
    dbms_output.put_line('假');
end if;
end;
列印:

2、type類型。
文法:表.欄位%TYPE
返回:某個表的欄位的實際類型。
作用:
PL/SQL指令碼中,有時定義的變數就是存取表中資料的。此時資料類型及長度就需要與欄位的定義一致。可以去查看該欄位的具體類型,但這樣做很麻煩;並且當欄位定義改變時,指令碼也需要修改。
所以使用type類型來引用該欄位的類型,更方便,維護性更好。

樣本:根據工號查詢員工姓名。
分析:要從emp表中擷取姓名,必須要用查詢語句。而要從查詢語句中擷取返回的值,要加上“into 變數”。

declare
    v_empno emp.empno%type;
    v_ename emp.ename%type;
begin
    v_empno:=7900;
    select ename into v_ename from emp where empno=7900;
    dbms_output.put_line(v_ename);
end;

3、rowtype類型
文法: 表%rowtype
作用: 儲存了某一行記錄的所有欄位的值。

樣本:根據工號為7900的員工的以下資訊:ename,job,sal,comm,hiredate。
第一種:如果用type類型,定義5個變數儲存查詢結果。代碼略。
第二種:如果用rowtype類型,只需要定義一個rowtype類型的變數。

代碼:
declare
    v_empno emp.empno%type;
    v_row emp%rowtype;
begin
    v_empno:=7900;
    select * into v_row from emp where empno=7900;
    dbms_output.put_line('ename='||v_row.ename);
    dbms_output.put_line('job='||v_row.job);
    dbms_output.put_line('sal='||v_row.sal);   
    dbms_output.put_line('comm='||v_row.comm);
    dbms_output.put_line('hiredate='||v_row.hiredate);   
end;
列印:
ename=JAMES
job=CLERK
sal=950
comm=
hiredate=03-12月-81

說明
·必須select *,或者根據表結構的順序寫出所有欄位名。
·使用rowtype類型最主要的限制在於表中不能有大對象欄位如:CLOB、BLOB。

4、record類型
record的意思是“記錄”。
有時,用type類型會定義太多的變數,用rowtype又會取到自己不關心的資料。
如何只取自己關心的欄位的值呢?此時就用record類型來自訂有多少個列。
文法:
type 類型名 is record(
   屬性名稱1 屬性類型,
   屬性名稱2 屬性類型
);
注意
1、屬性之間定義用的是逗號(,),不是分號(;)。
2、最後一個屬性名稱不需要再用“,”。

使用步驟有兩個:
1、先用type自訂一個新的類型,這個類型的變數能夠的變數與定義有關。
2、再用這個新的類型來定義一個變數,這個變數才能儲存實際的資料。

樣本:需求同上。
declare
--自訂一個類型
type myType is record(
    xm emp.ename%type, --姓名
    gzuo emp.job%type, --工作
    gzi emp.sal%type --工資
);
--使用自訂類型來定義變數
myValue myType;
begin
    select ename,job,sal into myValue from emp where empno=7844;
    dbms_output.put_line('ename='||myValue.xm);
    dbms_output.put_line('job='||myValue.gzuo);
    dbms_output.put_line('sal='||myValue.gzi);
end;

說明:
· 在查詢時必須與自訂類型的屬性順序一一對應。
·myValue中的屬性名稱也是自訂的,不是欄位名。

問題:上面的代碼比直接用type類型還多些,看不出優勢在什麼地方。為什麼還要用record?
回答:
在項目中,自訂類型通常會放到在包(package,後面會專門學習)中,這樣就可以在其它地方直接引用了。

樣本:
先在包中自訂類型:
create or replace package my_bao
as
type myType is record(
    xm emp.ename%type, --姓名
    gzuo emp.job%type, --工作
    gzi emp.sal%type --工資
);
end;
然後就可以在塊中直接使用該類型,只不過在類型前要加上包名:“my_bao”。
declare
--使用包中自訂類型來定義變數
myValue my_bao.myType;
begin
    select ename,job,sal into myValue from emp where empno=7844;
    dbms_output.put_line('ename='||myValue.xm);
    dbms_output.put_line('job='||myValue.gzuo);
    dbms_output.put_line('sal='||myValue.gzi);
end;

原文地址:http://hi.baidu.com/xydba/blog/item/7c136ec69565c145b319a8f5.html

 

 

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.