1.pl/sql
1.1 pl/sql是什麼;
pl/sql(Procedural Language extensions to the Strutured Query Language)過程化語言和結構化查詢語言結合的編程語言;
1.2 pl/sql和sql的不同;
1.2.1 pl/sql支持更多的數據類型和操作符;
1.2.2 可以過程化邏輯控制編程;
1.3 pl/sql怎麼過程化;
1.3.1 條件控制
1.3.2 循環控制
1.3.3 順序
2.pl/sql塊
2.1 pl/sql塊是什麼;
2.1.1 pl/sql是塊結構語言,pl/sql程序由邏輯塊組成;
2.1.2 邏輯塊包括函數、過程、匿名塊;
2.2 pl/sql匿名塊和格式;
沒有名字,格式:
[declare declarations] --聲明部分(不是必須)
begin
--executable statments; (必須)可執行部分 數據操作語句、事務控制語句
[exception handlers] --異常處理部分(不是必須的)
end; --(必須)
3.介紹pl/sql
3.1 和sql一樣不區分大小寫
3.2 變量和常量的聲明
3.2.1 變量的聲明和初始化;
變量名 數據類型[(範圍)] := 初始值;
變量名 數據類型[(範圍)] default 初始值;
3.2.2 常量的聲明
常量名 constant 數據類型[(範圍)] := 初始值;
3.3 數據類型和操作符
3.3.1 數據類型說明 個數,開始;
3.3.1.1 數字類型 number
3.3.1.2 字符類型 char,varchar,varchar2
3.3.1.3 時間類型 date,timestamp
3.3.1.4 大文本類型 clob,blob
3.3.1.5 布爾類型 boolean(true,false,null)
3.3.1.6 屬性類型 %type,%rowtype
3.3.2 操作符說明 (賦值:=,乘方**,範圍..,標識<< >>,連接||,--,/**/,關係運算符=,<>,!=,>,<,>=,<=);
3.4 打印語句;
set serveroutput on開始 以'/'結束來執行語句塊;
DBMS_OUTPUT.PUT_LINE('comment');
3.5 過程控制 (&varname);
3.5.1 條件
3.5.2 循環
3.5.3 順序
4.異常
4.1 預定義異常
4.2 自定義異常
4.2.1 raise 聲明異常出現在什麼情況
4.2.2 raise_application_error() -- (-20000 .. -20999);創建一個用戶定義的錯誤信息提示
預定義異常:
異常名 說明
--------------------------------------------------------------------------------
ACCESS_INTO_NULL 未初始化對象時出現
CASE_NOT_FOUND 在CASE語句中的選項與輸入的數據不匹配時出現
COLLECTION_IS_NULL 給尚未初始化的表或數組賦值時出現
CURSOR_ALREADY_OPEN 試圖重新打開已打開的遊標時出現,重新打開遊標
前必須先關閉
DUP_VAL_ON_INDEX 試圖將重複的值存儲在使用唯一索引的列中時出現
INVALID_CURSOR 執行非法遊標運算時出現,比如打開一個尚未打開
的遊標
INVALID_NUMBER 將字符串轉換爲數字時出現
LOGIN_DENIED 輸入的用戶名或密碼無效時出現
NO_DATA_FOUND 表中不存在請求的行時出現或者引用已刪除的元素時
STORAGE_ERROR 內存損壞或PL/SQL耗盡內存時出現
TOO_MANY_ROWS 執行select into語句後返回多行時出現
VALUE_ERROR 產生大小限制錯誤時出現
1.1 pl/sql是什麼;
pl/sql(Procedural Language extensions to the Strutured Query Language)過程化語言和結構化查詢語言結合的編程語言;
1.2 pl/sql和sql的不同;
1.2.1 pl/sql支持更多的數據類型和操作符;
1.2.2 可以過程化邏輯控制編程;
1.3 pl/sql怎麼過程化;
1.3.1 條件控制
1.3.2 循環控制
1.3.3 順序
2.pl/sql塊
2.1 pl/sql塊是什麼;
2.1.1 pl/sql是塊結構語言,pl/sql程序由邏輯塊組成;
2.1.2 邏輯塊包括函數、過程、匿名塊;
2.2 pl/sql匿名塊和格式;
沒有名字,格式:
[declare declarations] --聲明部分(不是必須)
begin
--executable statments; (必須)可執行部分 數據操作語句、事務控制語句
[exception handlers] --異常處理部分(不是必須的)
end; --(必須)
3.介紹pl/sql
3.1 和sql一樣不區分大小寫
3.2 變量和常量的聲明
3.2.1 變量的聲明和初始化;
變量名 數據類型[(範圍)] := 初始值;
變量名 數據類型[(範圍)] default 初始值;
3.2.2 常量的聲明
常量名 constant 數據類型[(範圍)] := 初始值;
3.3 數據類型和操作符
3.3.1 數據類型說明 個數,開始;
3.3.1.1 數字類型 number
3.3.1.2 字符類型 char,varchar,varchar2
3.3.1.3 時間類型 date,timestamp
3.3.1.4 大文本類型 clob,blob
3.3.1.5 布爾類型 boolean(true,false,null)
3.3.1.6 屬性類型 %type,%rowtype
3.3.2 操作符說明 (賦值:=,乘方**,範圍..,標識<< >>,連接||,--,/**/,關係運算符=,<>,!=,>,<,>=,<=);
3.4 打印語句;
set serveroutput on開始 以'/'結束來執行語句塊;
DBMS_OUTPUT.PUT_LINE('comment');
3.5 過程控制 (&varname);
3.5.1 條件
3.5.2 循環
3.5.3 順序
4.異常
4.1 預定義異常
4.2 自定義異常
4.2.1 raise 聲明異常出現在什麼情況
4.2.2 raise_application_error() -- (-20000 .. -20999);創建一個用戶定義的錯誤信息提示
預定義異常:
異常名 說明
--------------------------------------------------------------------------------
ACCESS_INTO_NULL 未初始化對象時出現
CASE_NOT_FOUND 在CASE語句中的選項與輸入的數據不匹配時出現
COLLECTION_IS_NULL 給尚未初始化的表或數組賦值時出現
CURSOR_ALREADY_OPEN 試圖重新打開已打開的遊標時出現,重新打開遊標
前必須先關閉
DUP_VAL_ON_INDEX 試圖將重複的值存儲在使用唯一索引的列中時出現
INVALID_CURSOR 執行非法遊標運算時出現,比如打開一個尚未打開
的遊標
INVALID_NUMBER 將字符串轉換爲數字時出現
LOGIN_DENIED 輸入的用戶名或密碼無效時出現
NO_DATA_FOUND 表中不存在請求的行時出現或者引用已刪除的元素時
STORAGE_ERROR 內存損壞或PL/SQL耗盡內存時出現
TOO_MANY_ROWS 執行select into語句後返回多行時出現
VALUE_ERROR 產生大小限制錯誤時出現
ZERO_DIVIDE 除數爲零時出現
/*
回顧
declare
--聲明部分
begin
--可執行部分
exception
end;
*/
--變量
declare
a number default 1; --初始化第一種方式
--a number := 1; --初始化第二中方式
var_col emp.ename%type;
var_col2 NUMBER;
var_const CONSTANT VARCHAR2(10); --常量
begin
a := 2; --給變量賦值
select ename,sal into var_col,var_col2 from emp
WHERE empno = 7788;
end;
--順序、條件、循環結構
/*
if 條件表達式 then
elsif 條件表達式 then
else
end if;
*/
/*
case 變量
when 值1 then
when 值2 then
...
else
end case;
*/
/*
循環體
loop
end loop;
第一種循環:
loop
exit when 表達式;
end;
第二種:
while 表達式
loop
end loop;
第三種:
for 變量 in 範圍
loop
end loop;
*/
DECLARE
salary NUMBER;
e_count NUMBER;
BEGIN
SELECT COUNT(*) INTO e_count FROM emp;
FOR n IN 1..e_count LOOP
SELECT sal INTO salary FROM
(SELECT ROWNUM rm,t.* FROM emp t)
WHERE rm = n;
dbms_output.put_line(salary);
END LOOP;
END;
declare
d_id number;
d_name dept.dname%type;
e_name emp.ename%type;
d_count number;
e_count number;
begin
select count(*) into d_count from dept;
for i in 1..d_count loop
select deptno,dname into d_id,d_name
from (select rownum num,t.* from dept t)
where num = i;
dbms_output.put_line('部門名稱:'||d_name);
select count(*) into e_count from emp
where deptno=d_id;
dbms_output.put('部門人員:');
for j in 1..e_count loop
select ename into e_name from
(select rownum num,t.* from emp t
where deptno = d_id)
where num = j;
if j<e_count then
dbms_output.put(e_name||',');
else
dbms_output.put(e_name);
end if;
end loop;
dbms_output.put_line('');
dbms_output.put_line('');
end loop;
end;
/*
6. 增加指定部門員工的工資10%。
然後打印所有的最新工資,
以及所有工資之和。
*/
DECLARE
e_sal NUMBER;
e_id NUMBER;
d_id NUMBER;
c NUMBER;
s_sum NUMBER DEFAULT 0;
BEGIN
d_id := &abc;
SELECT COUNT(*) INTO c FROM emp
WHERE deptno = d_id; --記錄數
FOR i IN 1..c LOOP
SELECT empno,sal INTO e_id,e_sal FROM
(SELECT ROWNUM num,t.* FROM emp t WHERE deptno=d_id)
WHERE num = i;
dbms_output.put_line(e_id||'更新前的薪水是:'||e_sal);
e_sal := e_sal*1.1;
dbms_output.put_line(e_id||'更新後的薪水是:'||e_sal);
UPDATE emp SET sal = e_sal WHERE empno = e_id;
s_sum := e_sal+s_sum;
END LOOP;
dbms_output.put_line('薪水總和是:'||s_sum);
COMMIT;
END;
--異常
DECLARE
a NUMBER;
BEGIN
SELECT sal INTO a FROM emp
WHERE ename = 'nimei';
dbms_output.put_line(a);
EXCEPTION
WHEN no_data_found THEN
dbms_output.put_line('未找到數據');
END;
DECLARE
re NUMBER;
BEGIN
re := 10/0;
EXCEPTION
WHEN zero_divide THEN
dbms_output.put_line('除數不能爲0');
END;
BEGIN
--正常的程序代碼 try
EXCEPTION
WHEN zero_divide THEN
dbms_output.put_line('除數不能爲0');
WHEN no_data_found THEN
dbms_output.put_line('未找到數據');
WHEN OTHERS THEN
dbms_output.put_line('所有異常');
END;
DECLARE
re NUMBER;
BEGIN
re := 10/0;
EXCEPTION
WHEN OTHERS THEN
dbms_output.put_line('異常');
END;
--自定義異常
DECLARE
n NUMBER;
my_exception EXCEPTION; --定義一個異常
BEGIN
n := &hhh;
IF n = 0 THEN
RAISE my_exception; --拋出異常的情景
END IF;
EXCEPTION
WHEN my_exception THEN
dbms_output.put_line('手賤....');
END;
--根據編號查詢工作崗位job,
--如果是查詢的是Persident,就拋出系統錯誤
--‘老總不出面’
DECLARE
e_job VARCHAR2(15);
per_exception EXCEPTION;
BEGIN
SELECT job INTO e_job FROM emp
WHERE empno=ⅈ
IF upper(e_job) = 'PRESIDENT' THEN
RAISE per_exception;
END IF;
EXCEPTION
WHEN per_exception THEN
raise_application_error(-20123,'老總不出面');
END;
--catch異常,不輸出打印語句,拋出系統錯誤
DECLARE
re NUMBER;
BEGIN
re := 10/0;
EXCEPTION
WHEN OTHERS THEN
--dbms_output.put_line('異常');
raise_application_error(-20100,'系統崩潰'); -- "-20000~-20999"
END;
--動態執行
BEGIN
EXECUTE IMMEDIATE
'CREATE TABLE tab(t NUMBER)';
END;
BEGIN
EXECUTE IMMEDIATE
'drop TABLE tab cascade constraints';
END;
BEGIN
EXECUTE IMMEDIATE
'SELECT * FROM emp WHERE empno = :1'
USING '7788';
END;