2016年7月25日 星期一

學習初級Oracle PL/SQL (四)

如何在PL/SQL程式跟踪變量(variables)

PL/SQL Data Types
VARCHAR2 - 資料型態儲存變動的字串長度,也就是說,假設宣告一個欄位資料型態為VARCHAR2,長度為5個字,若插入值'a',則欄位中的值為'a',長度只佔1個字.不同於CHAR,資料庫在比較VARCHAR2的值時是採取nonpadded的方式,也就是不會在字串後面補上空白使長度一致後才比較.VARCHAR2最大可裝4000bytes的字PL/SQL VARCHAR2 可裝32,767bytes的字.

Number - 大部分的時間你會在PL/SQL使用number數據類型.而且數據庫,PL/SQL有其他可用的數字數據類型. 例如,你可以使用PLS_INTEGER的類型
,它能存儲-2147483647+2147483647之間的整數.PLS_INTEGER可以直接進行算術運算(NUMBER數據類型不能直接進行算術運算,如果要計算,NUMBER必須先被轉換成二進制).所以在進行算術的時候PLS_INTEGERNUMBERBINARY_INTEGER快一些.但是, 除非你已非常熟習用PL/SQL撰寫procedure, 否則不必太深究它.

DATE - 大部分的時間你會在PL/SQL使用日期和時間,數據類型為DATE. NUMBER, PL/SQL也有額外的時間相關的數據類型.



Variables
PL/SQL程式中variables(變量)是一個臨時命名用來支持特定的數據類型.你必須先在PL/SQL宣告區delcare它們.

Variable 命名:
SQL或數據庫的數據類型,PL/SQL變量必須遵循命名規則:
1. 長度少於31字符.
2. 變量名稱必須以英文名開始,不分大小寫.
3. 變數可以是字母,數字,_ ,$,#
4. PL/SQL保留的關鍵字符不可以定義為變數
5. 每行只能夠定義一個標識符

變數名稱定義習慣:
Prefix
Data Type
c_
CURSOR
d_
DATE
n_
NUMBER
r_
ROW
t_
TABLE
v_
VARCHAR2


例如 table authors
SQL> desc authors
 Name                       Null?  Type
 ----------------------------------------- -------- ----------------------------
 ID                          NOT NULL NUMBER(38)
 NAME                    NOT NULL VARCHAR2(100)
 BIRTH_DATE         DATE
 GENDER                                 VARCHAR2(30)

變數可以命名為:
-       n_id
-       v_name
-       d_birth_date
-       v_gender

使用這些prefix的好處是, 你永遠知道該變量的數據類型和它的範圍. 此外,因為您所命名的名字明顯,你也知道它從哪裡來或到哪裡去. 所謂"明顯"意思是你不應該命名已經存在的標識符. 例如,不從birth_date列的值創建一個名為d_born變量或d_date_of_birthd_bday. 為什麼? 因為所有這些名稱變化只會讓指示不清楚.

現在你知道如何命名你的變量,讓我們來看看以下例子如何delcare.
語法: <variable_name> <data_type>;

declare
n_id                      number;
v_name                 varchar2(100);
d_birth_date          date;
v_gender               varchar2(30);
begin
...
end;

或使用Variable Anchors, anchor指利用關鍵字%TYPE用來對應table column的數據類型, 例子如下:
語法: <variable_name> <table_name>.<column_name>%TYPE;

n_id                 AUTHORS.id%TYPE;
v_name            AUTHORS.name%TYPE;
d_birth_date     AUTHORS.birth_date%TYPE;
v_gender          AUTHORS.gender%TYPE;

你現在知道了,通過使用anchor,變量按照來源使用相同的數據類型和大小.


Variable Assignments(變量分派)
變量分派要使用運算符,這是一個冒號後面跟一個等號( := ), 例子如下:

declare
...
begin
n_id                         :=     400;
v_name            :=     'STEVEN FEUERSTEIN';
d_birth_date     :=     to_date('19800101', 'YYYYMMDD');
v_gender          :=     'M';
end;

第二種分配一個值給一個變量方法是在SQL SELECT語句中使用INTO子句, 例子如下:

select id,name,birth_date,gender
into n_id,v_name,d_birth_date,v_gender
from AUTHORS where ........

默認情況下,變量是未初始化的,因此為NULL.你可以設定初始化值,通過declare簡單地分配他們的值聲明.例如,您可以初始化authors變量如下:
語法: <variable_name> <table_name>.<column_name>%TYPE := <value>;

declare
  n_id              AUTHORS.id%TYPE                 :=     400;
  v_name         AUTHORS.name%TYPE            :=     'STEVEN FEUERSTEIN';
  d_birth_date   AUTHORS.birth_date%TYPE     :=     to_date('19800101', 'YYYYMMDD');
  v_gender       AUTHORS.gender%TYPE         :=     NULL;
begin
...
end;



It’s Your Turn to Things Out
尋找下列錯誤原因:
begin
pl(scope1.gv_scope);
pl(scope1.my_scope_is_global());
pl(scope1.iv_scope);
pl(scope1.my_scope_is_instance());
end;
/
pl(scope1.iv_scope);
          *
ERROR at line 4:
ORA-06550: line 4, column 11:
PLS-00302: component 'IV_SCOPE' must be declared
ORA-06550: line 4, column 1:
PL/SQL: Statement ignored
ORA-06550: line 5, column 11:
PLS-00302: component 'MY_SCOPE_IS_INSTANCE' must be declared
ORA-06550: line 5, column 1:
PL/SQL: Statement ignored

create or replace package SCOPE1 as
gv_scope varchar2(80) := 'global variable';
function my_scope_is_global return varchar2;
procedure my_scope_is_global;
end scope1;
/
create or replace package body scope1 as
iv_scope varchar2(80) := 'instance variable';

function my_scope_is_instance return varchar2 is
v_answer_1 varchar2(3) := 'Yes';
 begin
        pl('can function see gv_scope?');
        pl(gv_scope);
        return v_answer_1;
end my_scope_is_instance;

function my_scope_is_global return varchar2 is
v_answer_2 varchar2(3) := 'Yes';
 begin
        pl('Can function see iv_scope?');
        pl(iv_scope);
        return v_answer_2;
end my_scope_is_global;

procedure my_scope_is_instance is
v_answer_3 varchar2(3) := 'Yes';
 begin
        pl('Can procedure see gv_scope?');
        pl(gv_scope);
end my_scope_is_instance;

procedure my_scope_is_global is
v_answer_4 varchar2(3) := 'Yes';
 begin
        pl('Can procedure see iv_scope?');
        pl(iv_scope);
end my_scope_is_global;
end scope1;
/


Answer:
create or replace package SCOPE1 as
gv_scope varchar2(80) := 'global variable';
iv_scope   varchar2(80) := 'instance variable';             -- missing
function my_scope_is_global return varchar2;
function my_scope_is_instance return varchar2;         -- missing
procedure my_scope_is_global;
procedure my_scope_is_instance;                            -- missing
end scope1;
/
create or replace package body scope1 as
iv_scope varchar2(80) := 'instance variable';               -- delete

function my_scope_is_instance return varchar2 is
v_answer_1 varchar2(3) := 'Yes';
 begin
        pl('can function see gv_scope?');
        pl(gv_scope);
        return v_answer_1;
end my_scope_is_instance;



沒有留言:

張貼留言