目錄
什麼是PL/SQL
SQL PL:Structured Query Language Procedual Language(IBM)
T-SQL:Transact-SQL(Microsoft)
PL/SQL:Procedual Language / Structured Query Language
是對SQL的擴展,改善了性能,具有可重用性,模塊化。
PL/SQL塊的類型
- 匿名塊:不能保存在數據庫中
- 過程函數和包:命名的PL/SQL塊,存儲在數據庫中,能多次執行
- 觸發器:發生觸發事件會執行
PL/SQL塊結構
1.定義部分
可選部分。與其它語言-樣,PL/SQL中使用的變量、常量、遊標和異常處理的名字都必須先定義後使用。並且必須定義在以DECLARE關鍵字開頭的定義部分。
2.可執行部分
該部分是PL/SQL塊的主體,包含該塊的可執行語句。該部分定義了塊的功能,是必須的。 由關鍵字BEGIN開始,以END結束。
3.異常處理部分
該部分包含塊的異常處理程序(錯誤處理程序)。當該塊程,序體中的某個語句出現異常(檢測到一個錯誤)時,oracle將程序控制轉到異常部分的相應的異常處理程序中進行進一步的處理。該部分由關鍵字EXCEPTION開始,END關鍵字結束。
DECLEAR-可選
變量定義 數據類型
BEGIN-必須
EXCEPTION-異常處理
END-可選
PL/SQL變量
- 標量型
- 複合型
- 引用型
- LOB型(大型對象)
標量數據類型
- CHAR
- VARCHAR
- DATE
- NUMBER
- BINARY_INTEGER
- PLS_INTEGER
- BOOLEAN
- BINARY_FLOAT
- BINAYR_DOUBLE
變量聲明
語法
identifier [CONSTANT] datatype [NOT NULL]
[ := | DEFAULT expr];
例如
Declare
v_hierdate DATE
c_tax_rate CONSTANT NUMBER(3,2) := 0.25
注意:多個變量同一數據類型不能一起定義,一行定義一個
select語句要有into語句
%TYPE屬性
變量的聲明可以直接映射到數據庫的某一列上 或整個表上,這樣可以採用%TYPE或 %ROWTYPE將這個變量錨定到數據庫相應的列或表。
例如:
...
v_balance NUMBER(7,2)
v_min_balance V_balance%TYPE := 10
...
其他變量
- boolean變量
三個類型:True,False,Null (注意空值)
邏輯運算符:AND,OR,NOT
- 大對象
三個類型:CLOB,BLOB,BFILE
- 外部變量
在某一程序主環境下聲明的一種變量
在declare之前聲明的,瞭解。
複習:空值判斷要用is;空值=空值返回假;nvl(v_x,0)實現的內容是若v_x爲空則賦成0
輸出
DBMS_OUTPUT.PUT_LINE
DECLARE
v_var varchar2(10);
BEGIN
SELECT ename into v_var
FROM emp
WHERE empno=7369;
DBMS_OUTPUT.PUT_LINE('僱員名=' || v_var);
END;
註釋
多行/**/
單行--
函數
過程語句中的有效函數:
- 單行字符(CONCAT、LENGTH、LOWER、SUBSTR等)
- 數據類型轉換(TO_ CHAR、TO_ DATE、 TO_ NUMBER等)
- 日期(ADD_ MONTHS、SYSDATE、MONTHS_ BETWEEN等)
過程語句中的無效函數:
- DECODE
- 分組函數(AVG、MIN、MAX、COUNT、SUM等)
- 分組函數僅在PL/SQL塊的SQL語句中適用
語句
可以用的
- select語句
- DML:insert update delete merge
- 事物:commit rollback savepoint
PL/SQL不能用的
- DDL: creat alter drop truncate rename
- DCL:授權grant revoke
查詢語句
是用來給變量賦值的。只能返回一行結果,必須使用into。
例:選擇並打印emp表中的最高薪水
DECLARE
v_sal emp.sal%type
BEGIN
SELECT max(sal)
INTO V_sal
FROM emp;
dbms_output.put_line(v_sal);
END;
DML語句
和SQL一致
例如:新增數據:新員工:工作職位‘MANAGER’,ID爲7788
BEGIN
INSERT INTO emp
(empno,ename,job,mgr,hiredate,sal)
VALUES(
1000,'TOM','MANAGER',7788,sysdate,4000);
END;
更新數據:增加analyst工資
DECLARE
v_sal emp.sal%type := 800;
BEGIN
UPDATE emp
SET sal = sal + v_sal
WHERE job = 'ANALYST'
END;
刪除數據:員工Smith離職
DECLARE
v_ename emp.ename%type := 'SMITH';
BEGIN
DELETE FROM emp
WHERE ename = v_ename
END;
事物控制語句
與SQL相同
BEGIN
INSERT INTO temp(x, y)
VALUES (1 ,'aaa') ;
SAVEPOINT a;
INSERT INTO temp (x,y)
VALUES (2, 'bbb') ;
SAVEPOINT b;
ROLLBACK TO SAVEPOINT a;
COMMIT;
END;
流程控制語句
IF語句
IF condition THEN
statements;
ELSEIF condiction THEN
statements;
ELSE
statements;
END IF;
邏輯表
注意一些不常見的情況
CASE語句
兩種用法
CASE selector
WHEN expression1 then result1
WHEN expression2 then result2
WHEN expressionN then resultN
ELSE resultN+1
END;
例:
求僱員的平均薪水,當薪水小於1000時,提示”薪水太低”,當薪水大於等於1000小於2000時,提示”起步的薪水”, 當薪水大於等於2000時,提示”已經步入軟件行業中”,使用CASE表達式來實現.
DECLARE
V_ _var varchar2(20);
V_sal emp.sal%type;
BEGIN
SELECT avg(sal) INTO V_ sal FROM emp;
V_ _var :=
CASE
WHEN V_ sal <1000 THEN‘薪水 太低’
WHEN V_ sal>=1000 AND V_ sal <2000 THEN '起步的薪水'
ELSE '已經步 入軟件行業中’
END;
Dbms_ output.put _line(v_ var);
End;
注意:要麼case後面加變量,when後面只有數字;要麼case後面沒東西,when後面加語句。二選一。
LOOP語句
三種循環:簡單循環(無條件循環)、for循環、while循環
- 簡單循環
先進循環再判斷(和do-whille有點像)
LOOP
statement
...
EXIT [WHEN condition]
END LOOP;
例子:
DECLARE
V_ count number(2):= 1;
V_ empno emp.empno%type;
V_ ename emp.ename%type:=‘ SMITH;
v_ job emp.job%type:=‘MANAGER';
BEGIN
SELECT max(empno) INTO V_ empno
FROM emp;
LOOP
INSERT INTO test(empno,ename,job)
VALUES ((v_ empno+v. count),v_ ename,v job);
V_ count := V_ count + 1;
EXIT WHEN v_ count >3;--注意循環邊界很重要
end loop;
END;
- for循環
FOR counter in [REVERSE]
lower_ bound.. upper_ bound LOOP
statement1;
statement2;
...
END LOOP; ;
counter不需要顯示聲明;循環下界大於上界循環就不會執行;reverse可以使計數器從大到小遞減。
DECLARE
V_ empno emp.empno%type;
V_ ename emp.ename%type := 'ljs';
V_ job emp. job%type := 'manager';
BEGIN
SELECT max(empno) INTO V_empno
FROM emp;
FOR V_ count IN 1..3 LOOP
INSERT INTO test(empno,ename,job)
VALUES ((v_ empno+v_ count),v_ ename,v_ job);
END LOOP;
END;
注意:循環變量counter自動維護,只讀,自己不能修改(修改會報錯)。
WHILE循環
WHILE condition LOOP
statement 1;
statement2;
...
END LOOP;
和簡單循環類似,先判斷條件再進循環(和while語句比較像)