變量的作用域: 變量可以使用的程式單元部分
可見性: 當一個變量在它的作用域中可以用一個不限定的名字來引用時
1.CONSTANT 聲明一個常量
2.NOT NULL 限制變量不能為空
3.:=value 用于為變量附初始值
例如
v_name DATE NOT NULL := SYSDATE
v_name INT NOT NULL DEFAULT 7369
變量在沒有被初始化的時候 變量會被初始化成null值 即使+1 依然還是null值
%TYPE
例子 用于定義相同類型的變量 用于綁定單個列的值
v_empno emp.empno%TYPE
%ROETYPE
用于綁定一整行的 所有列
v_emp emp%ROWTYPE
%TYPE 和 %ROWTYPE 隻提供類型資訊 并不能保證NOT NULL 限制
本地變量:在PLSQL塊或子程式中定義的變量僅在本地可用,如果在塊之外通路變量是非法的,這種變量稱為本地變量 當超出其作用域時,變量使用的記憶體将會被釋放,直到變量被重新定義并初始化
外部塊中定義的變量對于子塊來說是全局的,如果全局變量在子塊中又被重新聲明,那麼全局變量和本地聲明的變量在子塊的作用域是存在的,要通路外部塊的全局變量,需要使用限定修飾符。
當外部塊和内部快都同時聲明同一變量 優先通路本地的
12-8-5
<<outer>>
declare
v_empname varchar2(20);
begin
v_empname:='張三';
<<inner>>
v_empname:='李四';
dbms_output.put_line('内層塊的員工名稱:' || v_empname );
dbms_output.put_line('外層塊的員工名稱:' || outer.v_empname);
end;
dbms_output.put_line('outer員工名稱:' || v_empname);
12-9-1
資料類型
PLSQL 是一種靜态類型化的程式設計語言,靜态類型化又稱為強類型化,也就是說類型會在編譯時被檢查,而不是在運作時,增強程式的穩定性
标量類型:用來儲存單個值的資料類型,包含字元型,數字型,布爾型和日期型
複合類型:記錄 嵌套表 索引表和變長數組
引用類型:REF CURSOR 和REF 2種
LOB類型:用來處理二進制和大于4GB的字元串
每個oracle資料庫表都有一個名為ROWID的僞列。
SQL> select rowidtochar(rowid),ename,empno from emp;
ROWIDTOCHAR(ROWID) ENAME EMPNO
------------------ ---------- ----------
AAAQ+jAAEAAAAAeAAA SMITH 7369
AAAQ+jAAEAAAAAeAAB ALLEN 7499
AAAQ+jAAEAAAAAeAAC WARD 7521
AAAQ+jAAEAAAAAeAAD JONES 7566
AAAQ+jAAEAAAAAeAAE MARTIN 7654
AAAQ+jAAEAAAAAeAAF BLAKE 7698
ROWID:實體ROWID和邏輯ROWID
實體:辨別普通資料表中的一行資訊 邏輯:能夠辨別索引組織表中的一行資訊
UROWID 可以存儲 實體 邏輯 以及非 oracle 的ROWID
ROWID 可以顯著的加速資料檢索的性能。隻要行存在 實體ROWID 值就不會改變。
v_empname ROWID;
v_othersname VARCHAR(18);
select ROWID into v_empname from emp where empno=&empno;
dbms_output.put_line(v_empname);
v_othersname:=ROWIDTOCHAR(v_empname);
dbms_output.put_line(v_othersname);
數字類型 NUMBER:精度:所允許的的總長度 刻度:小數點右邊多少位 如果為負值 及小數點左邊多少位
指定刻度超過 四舍五入
v_num NUMBER(4,-1):=31451 41450
v_num NUMBER(4.3):= 3.1415926 3.142
用來存儲符号整型值 PLS_INTEGER BINARY_INTEGER
PLS_INTEGER 相對于NUMBER 來說需要更少的記憶體 來存儲資料而且在計算方面比NUMBER更有效率
NUMBER資料類型是以十進制格式進行存儲的 為了進行數學運算 需要轉換成二進制 是以速度會慢。
PLS_INTEGER 和 BINARY_INTEGER 都是以2的補碼格式進行計算的 PLS_INTEGER 在溢出時會觸發異常報錯 而 BINARY_INTEGER 會轉換成NUMBER 不會報錯。
SQL> select sessiontimezone from dual;
SESSIONTIMEZONE
---------------------------------------
+08:00
獲得目前時區
12-9-2
INTERVAL 類型
INTERVAL YEAR TO MONTH 用來存儲和操縱年和月之間的時間間隔
INTERVAL DAY TO SECOND 用來存儲和操縱天數,小時,分鐘和秒之間的時間間隔。
v_start timestamp;
v_end timestamp;
v_interval interval year to month;
v_year number;
v_month number;
v_start := TO_TIMESTAMP('2010-05-12','YYYY-MM-dd');
v_end := CURRENT_TIMESTAMP;
v_interval := (v_end - v_start) YEAR TO MONTH;
v_year := EXTRACT(YEAR FROM v_interval);
v_month := EXTRACT(MONTH FROM v_interval);
dbms_output.put_line('目前的interval值為:' || v_interval);
dbms_output.put_line('INTERVAL年份為:' || v_year || CHR(13)||CHR(10)|| 'INTERVAL月份為:'|| v_month );
v_interval := INTERVAL '01-03' YEAR TO MONTH;
dbms_output.put_line('目前INTERVAL值為:' || v_interval);
v_interval := INTERVAL '01' YEAR;
dbms_output.put_line('目前的INTERVAL值為:' || v_interval);
dbms_output.put_line('INTERVAL年份為' || v_year || CHR(13)|| CHR(10)||'INTERVAL月份為:'|| v_month );
v_interval := INTERVAL '03' MONTH;
dbms_output.put_line('目前的INTERVAL的值為:' || v_interval);
結果:
目前的interval值為:+04-07
INTERVAL年份為:4
INTERVAL月份為:7
目前INTERVAL值為:+01-03
目前的INTERVAL值為:+01-00
INTERVAL年份為1
INTERVAL月份為:0
目前的INTERVAL的值為:+00-03
引用類型
1.REF CURSOR 類型的變量通常稱為遊标變量
create or replace function selectallemployments
return sys_refcursor
as
st_cursor sys_refcursor;
open st_cursor for select * from emp;
return st_cursor;
x sys_refcursor;
v_emp emp%ROWTYPE;
x := selectallemployments;
loop
fetch x
into v_emp;
exit when x%NOTFOUND;
dbms_output.put_line('員工編号:' || v_emp.empno || '員工名稱:' || v_emp.ename);
end loop;
使用者自定義類型
引用遊标使用示例
subtype empcounttype is integer;
empcount empcounttype;
select count(*) into empcount from emp;
dbms_output.put_line('員勞工數為:' || empcount);
使用%TYPE
TYPE empnamelist is table of varchar2(20);
subtype namelist is empnamelist;
type emprec is record(
empno number(4),
ename varchar2(20)
);
subtype emprecord is emprec;
subtype empno is emp.empno%TYPE;
subtype emprow is emp%ROWTYPE;
null;
子類型具有的優勢:
1.可以檢查數值是否越界,這樣可以提高應用程式的可靠性。例如如果想要讓某個數字類型在0~9這個範圍之間,可以基于NUMBER類型定義一個子類型,這樣在指派時,如果資料溢出,編譯器會彈出錯誤提示
subtype numtype is number(1,0);
x_value numtype;
y_value numtype;
x_value := 3;
y_value := 10; 因為10 報錯 精度太高
2.未限制的子類型可以和它的基本類型互動使用
subtype numtype is number;
x_value number;
x_value:= 10;
y_value := x_value;
3.如果基類相同 那麼子類型可以互動使用
subtype numtype is varchar2(200);
x_value varchar2(20);
x_value:='This is a word';
y_value:=x_value;
12-10 資料類型轉換
顯示轉換
v_startdate DATE;
v_enddate DATE;
v_resultdate NUMBER;
v_startdate:=TO_DATE('2007-10-11','yyyy-MM-dd');
v_enddate:=TRUNC(SYSDATE);
v_resultdate:=v_enddate-v_startdate;
dbms_output.put_line('起始日期:'
|| TO_CHAR(v_startdate,'yyyy-MM-dd')
|| CHR(13)
||CHR(10)
||'結束日期:'
||TO_CHAR(v_enddate,'yyyy-MM-dd')
||CHR(13)
||'相差天數:'
||TO_CHAR(v_resultdate));
隐示轉換
v_startdate char(10);
v_enddate char(10);
v_result NUMBER(5);
select min(hiredate) into v_startdate from emp;
select trunc(sysdate) into v_enddate from dual;
dbms_output.put_line('起始日期:'
|| v_startdate
|| CHR(10)
|| '結束日期:'
|| v_enddate );
v_startdate:='200';
v_enddate:='400';
v_result:=v_enddate-v_startdate;
表達式
v_sal NUMBER;
v_result NUMBER;
select sal into v_sal from emp where empno=&empno;
v_result:=v_sal * (1+0.15);
運算符類型
指派運算符,連接配接運算符,邏輯運算符,比較運算符。
PLSQL中一個左值僅能有一個右值 val1:=val2:=val3:=val4=0 這樣是錯誤的
連接配接運算符
x varchar2(8):='你好';
y varchar2(8):='中國';
z varchar2(10);
dbms_output.put_line(x || z || NULL || y);
執行結果 因為z沒有指派 是以是一個null 連接配接一個null 2個就都不顯示
SQL> declare
2 x varchar2(8):='你好';
3 y varchar2(8):='中國';
4 z varchar2(10);
5 begin
6 dbms_output.put_line(x || z || NULL || y);
7 end;
8 /
你好中國
PL/SQL 過程已成功完成。
本文轉自潘闊 51CTO部落格,原文連結:,http://blog.51cto.com/pankuo/1630245如需轉載請自行聯系原作者