簡介:PL/SQL是是甲骨文公司開發,嵌入在Oracle數據庫中的編程語言。
基礎
- 塊結構
- declare 聲明部分 – 所有變量,游標,子程序,和其他元素
- begin - end ; – 程序主體,可執行命令
- 常見符號解釋:
符號 | 含義 |
---|---|
|| | 字符串連接符 |
:+ | 賦值運算符 |
% | 獲得相同的數據類型 |
= | 相等運算符 |
- 變量的常見類型:
類型 | 含義 |
---|---|
varchar2 | 可變長字符串 |
int | 整數類型 |
number (precision,scale) | precision表示數字中的有效位,如果沒有指定precision的話,oracle將使用38作為精度, 如果scale大于零,表示數字精度到小數點右邊的位數;scale默認設置為0;如果scale小于零,oracle將把該數字取舍到小數點左邊的指定位數 |
clob | 用于存儲字符大塊數據在數據庫中 大小為 8 - 128 TB |
date | 日期和時間 |
- 數組 TYPE varray_type_name IS VARRAY(n) OF element_type
DECLARE
type namesarray IS VARRAY(5) OF VARCHAR2(10);
type grades IS VARRAY(5) OF INTEGER;
names namesarray; --拿到數組的引用,下面就可以變長使用該數組
marks grades;
total integer;
BEGIN
names := namesarray('Kavita', 'Pritam', 'Ayan', 'Rishav', 'Aziz');
marks:= grades(98, 97, 78, 87, 92);
total := names.count; --求數組的長度
dbms_output.put_line('Total '|| total || ' Students');
FOR i in 1 .. total LOOP
dbms_output.put_line('Student: ' || names(i) || ' Marks: ' || marks(i));
END LOOP;
END;
- 全局變量與局部變量
DECLARE
-- Global variables
num1 number := 95;
BEGIN
DECLARE
-- Local variables
num1 number := 195;
BEGIN
END;
END;
- 常量
PI constant number := 3.14;
- SELECT INTO 取值出來使用: SELECT 表中變量 INTO 定義變量 FROM XXX
declare
c_id customers.id%type := 1;
c_name customers.name%type;
c_addr customers.address%type;
c_sal customers.salary%type;
begin
select name,address,salary into c_name,c_addr,c_sal from customers where id = c_id;
dbms_output.put_line('Customer '||c_name||' from '||c_addr||' earns '||c_sal);
end;
- 控制語句
- IF 語句:if 使用 end if 結束
DECLARE
a number(3) := 100;
BEGIN
IF ( a = 10 ) THEN
dbms_output.put_line('Value of a is 10' );
ELSIF ( a = 20 ) THEN
dbms_output.put_line('Value of a is 20' );
ELSE
dbms_output.put_line('None of the values is matching');
END IF;
dbms_output.put_line('Exact value of a is: '|| a );
END;
?2. CASE語句: 以end case 結束
declare
grade char(1) := 'A';
begin
case grade
when 'A' then dbms_output.put_line('A');
when 'B' then dbms_output.put_line('B');
else dbms_output.put_line('NO');
end case;
end;
- 循環控制語句
?1. LOOP :已END LOOP結束
DECLARE
x number := 10;
BEGIN
LOOP
dbms_output.put_line(x);
x := x + 10;
IF x > 50 THEN
exit;
END IF;
END LOOP;
-- after exit, control resumes here
dbms_output.put_line('After Exit x is: ' || x);
END;
?2. WHILE: 已END LOOP結束
DECLARE
a number(2) := 10;
BEGIN
WHILE a < 20 LOOP
dbms_output.put_line('value of a: ' || a);
a := a + 1;
END LOOP;
END;
- FOR: 已END LOOP結束
DECLARE
a number(2);
BEGIN
FOR a in 10 .. 20 LOOP -- 10 .. 20 表示10-20 全包含
dbms_output.put_line('value of a: ' || a);
END LOOP;
END;
進階 (進步進階無所謂半小時就看完了)
- 兩種子程序:
?參數 in :入參, out : 返回值, in out :入參且是返回值
create PROCEDURE squareNum(x IN OUT number) IS
BEGIN
x := x * x;
END;
? 1. 函數:這些子程序返回一個值,主要用于計算并返回一個值。
??1.1. 創建函數
CREATE [OR REPLACE] FUNCTION function_name
[(parameter_name [IN | OUT | IN OUT] type [, ...])] RETURN return_datatype
{IS | AS}
BEGIN
< function_body >
RETURN XXX;
END [function_name];
- 過程:這些子程序沒有直接返回值,主要用于執行操作。
2.1. 創建過程
Create PROCEDURE findMin(x IN number, y IN number, z OUT number) IS
BEGIN
IF x < y THEN
z:= x;
ELSE
z:= y;
END IF;
END;
?2.2. 銷毀過程
drop procedure procedure_name;
- 游標
- 隱式游標
DML操作和單行SELECT語句會使用隱式游標,它們是:
?* 插入操作:INSERT。
?* 更新操作:UPDATE。
?* 刪除操作:DELETE。
?* 單行查詢操作:SELECT ... INTO ...。
當系統使用一個隱式游標時,可以通過隱式游標的屬性來了解操作的狀態和結果,進而控制程序的流程。隱式游標可以使用名字SQL來訪問,但要注意,通過SQL游標名總是只能訪問前一個DML操作或單行SELECT操作的游標屬性。所以通常在剛剛執行完操作之后,立即使用SQL游標名來訪問屬性。游標的屬性有四種,如下所示:
- 隱式游標
??? * sql%found (布爾類型,默認值為null)INSERT、UPDATE、DELETE 成功返回TRUE
??? * sql%notfound(布爾類型,默認值為null)INSERT、UPDATE、DELETE 不成功返回TRUE
??? * sql%rowcount(數值類型默認值為0)返回INSERT、UPDATE、DELETE 影響的行數
??? * sql%isopen(布爾類型)隱式游標返回FALSE,
?2. 顯式游標
? * 聲明游標 cursor c_customer is select * from customers;
?? * 打開游標 open c_customer;
?? * 獲取游標 fetch c_customers into c_addr,c_name,c_salary;
?? * 關閉游標 close c_customers;
declare c_id customers.id%type;
c_name customers.name%type;
c_addr customers.address%type;
cursor c_customers is select id,name,address from customers;
begin
open c_customers;
loop
fetch c_customers into c_id,c_name,c_addr;
exit when c_customers%notfound;
dbms_output.put_line(c_id || ' ' || c_name || ' ' || c_addr);
end loop;
close c_customers;
end;
- 異常處理
- 異常聲明 : exception_name exception;
- 拋出異常 : raise exception_name;
- 捕獲異常 : when exception_name then…
DECLARE
c_id customers.id%type := &c_id; -- 接收用戶輸入的值,運行的時候會彈出一個輸入框。
c_name customers.name%type;
c_addr customers.address%type;
-- user defined exception
ex_invalid_id EXCEPTION;
BEGIN
IF c_id <= 0 THEN
RAISE ex_invalid_id;
ELSE
SELECT name, address INTO c_name, c_addr
FROM customers
WHERE id = c_id;
DBMS_OUTPUT.PUT_LINE ('Name: '|| c_name);
DBMS_OUTPUT.PUT_LINE ('Address: ' || c_addr);
END IF;
EXCEPTION
WHEN ex_invalid_id THEN
dbms_output.put_line('ID must be greater than zero!');
WHEN no_data_found THEN
dbms_output.put_line('No such customer!');
WHEN others THEN
dbms_output.put_line('Error!');
END;
TIPS
- dbms_output.put_line() 輸出日志