天天看點

PLSQL 之類型、變量和結構

在《.Net程式員學用Oracle系列(5):三大資料類型》一文中詳細地講述了 Oracle 的基本資料類型,文中還提到,除基本資料類型之外,Oracle 還在文法上支援一些非固有數值類型。

事實上,Oracle 在文法上支援的資料類型遠不止于此,Oracle 還支援一些複雜而強大的資料類型。如屬性類型<code>%TYPE</code>和<code>%ROWTYPE</code>,記錄類型 RECORD,集合類型 VARRAY 和 TABLE 等。本節将會介紹實用的屬性類型和靈活的記錄類型。

屬性類型是一種可以直接引用資料庫中列的資料類型來描述變量類型的類型。Oracle 提供了兩種屬性類型,分别是<code>%TYPE</code>和<code>%ROWTYPE</code>,下文将逐一說明。

%TYPE:該屬性允許在聲明中引用資料庫中的列或先前聲明的變量的資料類型,而不是寫死類型名稱。在聲明常量、變量和參數時,都可以使用<code>%TYPE</code>屬性作為資料類型說明符。如果引用的類型被更改,則聲明也将自動更新,這點有利于後期代碼維護。

示例:

%ROWTYPE:該屬性可以表示資料庫中表或遊标的行的記錄類型。使用<code>%ROWTYPE</code>聲明的變量可以存儲從表中選擇或從遊标或遊标變量擷取的整行資料,且變量記錄中的字段和每行中的相應列具有相同的名稱和資料類型。

想要更多的了解屬性類型可參考:《Database PL/SQL User's Guide and Reference: %TYPE Attribute》和《Database PL/SQL User's Guide and Reference: %ROWTYPE Attribute》。

記錄類型是由單行多列标量構成的複合結構。可以看做是一種使用者自定義的資料類型,提供了将一個或多個标量封裝成一個對象進行操作的能力。在使用記錄資料類型的變量時,需要在聲明部分先定義記錄的成員變量,然後在執行部分引用該記錄變量本身或其中的成員。但不可以對記錄做整體性的比較運算,如判斷記錄類型的變量是否為 NULL。

記錄類型和<code>%ROWTYPE</code>屬性在用途上比較相似,差別在于前者是自定義結構,而後者為表結構,前者比較靈活,而後者比較友善。

一般計算機程式設計語言中都有變量的概念,PL/SQL 也不例外,變量用于存儲計算結果和表示可變狀态,本節将着重介紹在 PL/SQL 中變量如何定義及指派。另外,PL/SQL 中也有常量,隻是極少有人使用,有興趣的讀者可以參考《Oracle Database PL/SQL Language Reference: Constant》。

在 PL/SQL 中定義變量的可選類型非常多,包括 Oracle 中常見的三大類基本資料類型,以及 Oracle 在文法上支援的諸多非固有資料類型。如整形(INT/INTEGER)、布爾類型(BOOLEAN)等 Oracle 本身并不支援,卻在 PL/SQL 中可用的資料類型。

在 PL/SQL 中定義變量與 C# 中定義變量本質上并無差別,不同的是 PL/SQL 中的變量得集中定義,變量定義區域得用<code>DECLARE</code>關鍵字開頭,且每行隻能定義一個變量。如果是 SQL*Plus 環境則必須用<code>VAR[IABLE]</code>開頭。

文法:

如果使用了 NOT NULL 則必須給變量賦初始值。另外,在命名變量的時候還需要遵守以下命名規則:

1、變量名必須以字母開頭。

2、變量名長度不能超過 30 個字元。

3、變量名中不能含有空格。

4、同一語句塊内變量名不能重複。

5、變量名不能與查詢中的列名相同。

給 PL/SQL 變量指派的寫法與給 C# 字段指派寫法基本一樣,既可以在定義變量時就賦給它一個初始值,也可以在使用之前給它指派,如果不指派也會有預設值。唯一的差別就是,C# 中類型不同預設值也不同,而 PL/SQL 中所有類型的預設值都一樣,都是 NULL。

在 PL/SQL 中還有一點比較怪的就是,可能所有程式設計語言的指派操作符都是<code>=</code>,而 PL/SQL 中的指派操作符卻偏偏是<code>:=</code>。而且 Oracle 相關的 API 中參數寫法也與其它大多數資料庫不同。

示例一(普通 PL/SQL 環境):

示例二(SQL*Plus 環境):

和普通程式設計語言一樣,PL/SQL 中也有常見的三大控制結構以及順序控制語句——GOTO。本節将重點講述被廣泛接受的三大控制結構,至于不受待見的 GOTO 語句,有興趣的讀者可以參考《Oracle Database PL/SQL User's Guide and Reference: Using the GOTO Statement》。

順序結構是面向過程程式設計中最基本、最簡單、最常用的程式控制結構。順序結構用于表示若幹個依次執行的處理步驟,表現形式就是線性結構,一個方向走下去、不拐彎。使用時隻要按照解決問題的順序寫出相應的語句就行,它的執行順序是自上而下、依次執行。

PL/SQL 中提供了兩種選擇結構,分别是<code>IF</code>結構和<code>CASE</code>結構。其中<code>IF</code>結構有三種變體,<code>CASE</code>結構有兩種變體。下文将逐一講述各個選擇語句:

IF 結構變體一:

IF 結構變體二:

IF 結構變體三:

注意:IF 結構變體三中有個巨坑,就是 IF 和 ELSE 之間的分支寫法,不是 ELSE IF 也不是 ELSEIF 而是 ELSIF。盡管你寫成 ELSE IF 編輯器也有智能提示,但當你執行的時候就會報<code>ORA-06550</code>的錯,而且這個錯誤的描述正常人基本沒可能看懂。

CASE 結構變體一

CASE 結構變體二

與多分支的 IF 語句相比,CASE 語句更可讀、更高效,是以當程式分支較多時,應盡可能的使用 CASE 而不是 IF。CASE 語句的 ELSE 子句是可選的。但如果省略 ELSE 字句,PL/SQL 将為 CASE 語句添加以下隐式的 ELSE 子句:

換句話說,如果你省略了 ELSE 子句,且 CASE 語句與 WHEN 子句不比對,PL/SQL 就會引發預定義的異常<code>CASE_NOT_FOUND</code>。

PL/SQL 中提供了三種循環結構,分别是<code>LOOP</code>、<code>WHILE LOOP</code>和<code>FOR LOOP</code>。另外 PL/SQL 還提供了<code>EXIT</code>語句用于退出目前循環。下文将逐一講述各個循環語句:

LOOP 循環

示例一:

示例二(嵌套循環):

示例三(标記循環):

WHILE LOOP 循環

FOR LOOP 循環

示例一(正向循環):

示例二(反向循環):

注意:FOR LOOP 循環中的計數器(變量)可以被讀取,但不能被修改。另外,在 LOOP 循環的示例中用到的 EXIT 和循環标記,同樣可用于 WHILE LOOP 循環和 FOR LOOP 循環中

本文轉自 sshpp 51CTO部落格,原文連結:http://blog.51cto.com/12902932/1926164,如需轉載請自行聯系原作者