作者:gqk:
1,什么是plsql:
是專用於Oracle服務器,在SQL基礎之上,添加了一些過程化控制語句,叫PLSQL過程化包括有:類型定義,判斷,循環,游標,異常或例外處理。。。
PLSQL強調過程
2,Plsql語句塊:
PL/SQL程序都是以塊(block)為基本單位,整個PL/SQL塊分三部分:
- 聲明部分(用declare開頭)
- 執行部分(以 begin開頭)其中執行部分是必須的,其他兩個部分可選
- 異常處理部分(以exception開頭)
- 結束:end

--基本輸出語句:
BEGIN
dbms_output.put_line('hello,world');
END;
--基本輸出語句
BEGIN
dbms_output.put_line('hello,world');
dbms_output.put_line(157);
dbms_output.put_line(sysdate);
dbms_output.put_line(true);--不能傳入布爾值
END;
3,Plsql語句塊分類:
- 匿名塊:動態構造只執行一次(main)
- 子程序:存儲在數據庫中的存儲過程,函數及包等。當在數據庫建立好后可以在其他子程序中調用
- 觸發器:當數據庫發生操作時,會觸發一些事件,從而自動執行相應的程序
4,Plsql中的變量類型:

5,變量的使用:
plsql中聲明和執行部分要嚴格分開,在java中時先聲明后寫變量plsql中相反 先聲明在寫數據類型:
變量在聲明后沒有賦值輸出結果為空:
變量的聲明和初始化:(boolean中只能聲明不能輸出)
DECLARE
i NUMBER(4) := 157;
j NUMBER(6);
c VARCHAR2(200) := 'HELLO,WORLD';
d DATE := sysdate;
b BOOLEAN := TRUE;
BEGIN
j := 1000;--只能寫在執行部分
dbms_output.put_line('i=' || i);
dbms_output.put_line('j=' || j);
dbms_output.put_line('c=' || c);
dbms_output.put_line('d=' || d);
END;

在聲明快中對常量的聲明:
變量名稱 【constant】 type 【not null】 【:value】
DECLARE
c CONSTANT NUMBER(4) := 100;
c2 NUMBER(4) NOT NULL := 101;
BEGIN
--c := 101; --常量不能重復賦值
dbms_output.put_line('c=' || c);
dbms_output.put_line('c2=' || c2);
END;
--空語句 NULL 執行語句中必須寫東西
DECLARE
c CONSTANT NUMBER(4) := 100;
c2 NUMBER(4) NOT NULL := 101;
BEGIN
NULL;--空語句,作為占位符使用
END;
6,PLSQL中使用sql:
--更新100員工,工資增加1塊錢 :(不能再執行塊中直接輸出select語句)
- 聲明變量:員工的編號
- 聲明變量:工資追加的錢數
DECLARE
v_empid BINARY_INTEGER := 100;
v_money BINARY_INTEGER := 1;
BEGIN
UPDATE employees SET salary=salary+v_money
WHERE employee_id=v_empid;
COMMIT;
END;
PLSQL中使用SQL語句的幾種情況:
- DML或DCL語句:直接執行
- 查詢語句:SELECT...INTO 或者 游標
- DDL語句:動態SQL執行
7,SELECT...INTO...的使用:
語法:SELECT 列1,列2,…… INTO 變量1,變量2,……
--查詢某個員工編號的姓名和工資:
- 員工編號
- 姓名
- 工資
列和變量的順序,個數必須保持一致(如果沒有數據則會拋出異常,返回的結果超過一行 也會有異常)
DECLARE
v_empid BINARY_INTEGER := 101;
v_name VARCHAR2(50);
v_salary NUMBER(8,2);
BEGIN
SELECT last_name,salary
INTO v_name,v_salary
FROM employees
WHERE employee_id=v_empid;
dbms_output.put_line(v_empid || ',' || v_name || ',' || v_salary);
END;
--查詢某個員工編號的姓名,工資,入職日期,部門編號:(以上思路 我們需要聲明多個變量)
DECLARE
v_empid BINARY_INTEGER := 101;
v_name VARCHAR2(50);
v_salary NUMBER(8,2);
v_hiredate DATE;
v_deptid BINARY_INTEGER;
BEGIN
SELECT last_name,salary,hire_date,department_id
INTO v_name,v_salary,v_hiredate,v_deptid
FROM employees
WHERE employee_id=v_empid;
dbms_output.put_line(v_empid || ',' || v_name || ','
|| v_salary || ',' || v_hiredate || ',' || v_deptid);
END;
java中處理多個數據我們可以封裝為對象:
plsql中可以聲明記錄類型:時把邏輯相關的數據作為一個單元存儲起來:

--記錄類型record
--查詢某個員工編號的姓名,工資,入職日期,部門編號
DECLARE
TYPE emp_record_type IS RECORD (
empid BINARY_INTEGER := 102,
ename VARCHAR2(50),
salary NUMBER(8,2),
hiredate DATE,
deptid BINARY_INTEGER
);
e emp_record_type;
BEGIN
SELECT employee_id,last_name,salary,hire_date,department_id
INTO e
FROM employees
WHERE employee_id=e.empid;
dbms_output.put_line(e.empid);
dbms_output.put_line(e.ename);
dbms_output.put_line(e.salary);
dbms_output.put_line(e.hiredate);
dbms_output.put_line(e.deptid);
END;
--參照引用類型:參照已有的數據類型
--參照引用類型
--參照引用變量類型:變量名稱%TYPE
--參照引用表中的列類型:表名.列名%TYPE
--參照引用表的記錄類型:表名%ROWTYPE
demo:
DECLARE
i NUMBER(4);
j i%TYPE := 100;--參照i的類型
k employees.employee_id%TYPE := 101;--參照員工表中員工編號的數據類型
BEGIN
dbms_output.put_line('j=' || j);
dbms_output.put_line('k=' || k);
END;
--查詢某個員工編號的姓名,工資,入職日期,部門編號(參照類型)
DECLARE
TYPE emp_record_type IS RECORD (
empid employees.employee_id%TYPE := 102,
ename employees.last_name%TYPE,
salary employees.salary%TYPE,
hiredate employees.hire_date%TYPE,
deptid employees.department_id%TYPE
);
e emp_record_type;
BEGIN
SELECT employee_id,last_name,salary,hire_date,department_id
INTO e
FROM employees
WHERE employee_id=e.empid;
dbms_output.put_line(e.empid);
dbms_output.put_line(e.ename);
dbms_output.put_line(e.salary);
dbms_output.put_line(e.hiredate);
dbms_output.put_line(e.deptid);
END;
--查詢某個員工編號的姓名,工資,入職日期,部門編號(參照引用表的記錄類型)
DECLARE
e employees%ROWTYPE;
BEGIN
e.employee_id := 103;
SELECT *
INTO e
FROM employees
WHERE employee_id=e.employee_id;
dbms_output.put_line(e.employee_id);
dbms_output.put_line(e.last_name);
dbms_output.put_line(e.salary);
dbms_output.put_line(to_char(e.hire_date,'yyyy-mm-dd'));
dbms_output.put_line(e.department_id);
END;
--PLSQL表類型
/*
TYPE 自定義類型名稱 IS TABLE OF 元素類型
INDEX BY BINARY_INTEGER;
*/
DECLARE
TYPE name_table_type IS TABLE OF VARCHAR2(50)
INDEX BY BINARY_INTEGER;
n name_table_type;
BEGIN
n(-7) := 'tom';
n(4) := 'jack';
n(9) := 'rose';
dbms_output.put_line('元素的長度:' || n.count);
dbms_output.put_line(n(4));
END;
--表類型的常用屬性
DECLARE
TYPE name_table_type IS TABLE OF VARCHAR2(50)
INDEX BY BINARY_INTEGER;
n name_table_type;
BEGIN
--設置元素
n(-5) := 'tom';
n(3) := 'jack';
n(17) := 'rose';
n(23) := 'zhang';
n(24) := 'wangwu';
--刪除指定下標的元素
--n.delete(17);
--刪除一個范圍的元素
--n.delete(10,24);
--刪除所有元素
--n.delete;
--返回元素長度
dbms_output.put_line('元素個數:' || n.count);
--判斷下標是否存在
IF n.exists(17) THEN
dbms_output.put_line('true');
ELSE
dbms_output.put_line('false');
END IF;
--輸出最小下標
dbms_output.put_line(n.first);
--輸出最大下標
dbms_output.put_line(n.last);
--返回指定下標的元素
dbms_output.put_line(n(3));
--返回上一個或下一個存在的下標,如果沒有,返回NULL
dbms_output.put_line(n.next(10));
dbms_output.put_line(n.prior(10));
END;
--BULK COLLECT INTO:把查詢結果一次性賦給一個表類型的變量,下標自動從1開始遞增
--查詢所有的員工姓名,存儲到一個表類型的變量中
DECLARE
TYPE name_table_type IS TABLE OF VARCHAR2(50)
INDEX BY BINARY_INTEGER;
n name_table_type;
BEGIN
SELECT last_name BULK COLLECT INTO n
FROM employees;
dbms_output.put_line('元素長度:' || n.count);
dbms_output.put_line(n(2));
END;
--查詢所有的員工信息,存儲到一個表類型的變量中
DECLARE
TYPE emp_table_type IS TABLE OF employees%ROWTYPE
INDEX BY BINARY_INTEGER;
e emp_table_type;
BEGIN
SELECT * BULK COLLECT INTO e
FROM employees;
dbms_output.put_line('元素長度:' || e.count);
dbms_output.put_line(e(2).last_name);
dbms_output.put_line(e(3).salary);
END;
8,DML語句返回值:
--RETURNING語句:DML操作返回值賦給變量
RETURN 列1,列2,... INTO 變量1,變量2,...
--更新某個員工的工資,輸出這個員工姓名,新工資

DECLARE
v_empid employees.employee_id%TYPE := 100;
v_name employees.last_name%TYPE;
v_money employees.salary%TYPE := 1;
v_salary employees.salary%TYPE;
BEGIN
UPDATE employees
SET salary=salary+v_money
WHERE employee_id=v_empid
RETURNING last_name,salary
INTO v_name,v_salary;
dbms_output.put_line('姓名:' || v_name);
dbms_output.put_line('新工資:' || v_salary);
END;
--插入語句中使用RETURNING語句:
DECLARE
d dept%ROWTYPE;
BEGIN
INSERT INTO dept VALUES (50,'AA','BB')
RETURN deptno,dname,loc INTO d;
dbms_output.put_line(d.deptno);
dbms_output.put_line(d.dname);
dbms_output.put_line(d.loc);
END;
--刪除語句中使用RETURNING語句
DECLARE
d dept%ROWTYPE;
BEGIN
DELETE FROM dept
WHERE deptno=50
RETURN deptno,dname,loc INTO d;
dbms_output.put_line(d.deptno);
dbms_output.put_line(d.dname);
dbms_output.put_line(d.loc);
END;
--DML操作返回多行數據
--更新某個部門的員工的工資,返回被更新的員工姓名,新工資
DECLARE
TYPE emp_record_type IS RECORD (
ename employees.last_name%TYPE,
salary employees.salary%TYPE
);
TYPE emp_table_type IS TABLE OF emp_record_type
INDEX BY BINARY_INTEGER;
e emp_table_type;
BEGIN
UPDATE employees
SET salary=salary+1
WHERE department_id=50
RETURN last_name,salary BULK COLLECT INTO e;
dbms_output.put_line('更新了' || e.count || '個員工');
dbms_output.put_line(e(1).ename || ',' || e(1).salary);
END;
