PL/SQL基礎

1 PL/SQL概述

pl/sql是oracle對sql語言的過程化擴展。(在sql中增加了過程處理語句如分支,循環等)使sql語言具有過程處理能力。

1.1 PL/SQL的提出

pl/sql是面向過程的語言,結合了sql語言的數據操縱能力如增刪改查和過程語言的數據處理能力。而不同數據庫對sql有不同的擴展。

  • oracle: pl/sql
  • db2: sql/pl
  • sql server: t-sql

2 基礎語法

[declare] 聲明部分可選
begin
執行部分必須
如打印helloword
dbms_output.put_line(‘hello word’);
[exception] 異常處理部分可選
end;

2.1 基本類型變量

pl/sql 有以下幾種類型的變量分別是
number,boolean,char,varchar2,date,long
我們通常在declare部分聲明變量,可以採用以下兩種方式對變量賦值

  • := 比如 vsal number:=1000;(一般用於給單個變量賦值)
  • into 一般在pl/sql程序體中將某個字段值賦給變量(可以以多對多的形式對變量進行賦值) 比如
declare
vsal number;
vname varchar2;
begin
select sal,ename into vsal,vname from emp where empno=666;
end;

2.2 引用類型變量

我們也可以以表中某個字段的類型作爲變量的類型,引用類型變量的語法格式爲
變量名 表名.列名%type
如 esal emp.sal%type;

2.3 記錄型變量

記錄型變量代表的是表中的一行數據,以一整行的數據作爲一個變量類型
把記錄型變量理解爲一個數組,而在這個數組中的每一個元素代表這一行中的每一列數據。格式爲
變量名 表名%rowtype
記錄變量分量的使用 變量名.字段名
比如我們輸出員工號爲666的員工的姓名和薪水

set serveroutput on  --打開屏幕輸出開關
declare
emp_info emp%rowtype;
begin
select * into emp_info from emp where empno=666;
dbms_output.put_line('姓名是:'||emp_info.ename||'薪水爲'||emp_info.sal);
end;

2.4 選擇語句的使用

基本形式:
if 條件 then 語句;
elsif 條件 then 語句;
else 語句;
end if;

2.5 循環語句的使用

2.5.1 while語句

基本形式:
while 條件 loop
執行部分
end loop;
表示當滿足條件時執行執行部分的內容,不滿足條件時退出循環。
示例:打印數字1-10

set serveroutput on
declare
num number:=1;
begin
while num<11 loop
dbms_output.put_line(num);
num:=num+1;
end loop;
end;

2.5.2 loop語句

基本形式:
loop
執行部分
exit when 條件;
執行部分
end loop;
這裏需要說明的是當條件爲true時退出循環,執行部分可以根據我們的需要寫在上邊或下邊,或上下各寫一部分。
示例:打印數字1-10

set serveroutput on
declare
num number:=1;
begin
loop
exit when num>10;
dbms_output.put_line(num);
num:=num+1;
end loop;
end;

2.5.3 for語句

基本形式:
for 循環變量 in [reverse] 下限..上限 loop
執行部分
loop;
這裏需要說明的是for語句是一個可控制循環次數的循環控制語句。它有一個循環計數器來控制循環進行的次數。

  • 循環變量用來做計數器,默認情況下是自動遞增的。
  • reverse 加這個關鍵字表示計數器是遞減的。
  • 下限 計數器的下限值,當計數器的值小於下限值是會終止循環。
  • 上限 計數器的上限值,當計數器的值大於上限值是會終止循環。

示例:打印倒序數字1-10

set serveroutput on
declare
num number:=1;
begin
for num in reverse 1..10
loop
dbms_output.put_line(num);
end loop;
end;

以上三種循環其實loop循環是用的最多的,在遊標的使用中就能發現loop循環是最方便的。

3 遊標(光標)

3.1 遊標的概述

遊標就是一個結果集,我們通過遊標pl/sql程序可以一次性處理查詢結果集中的一行或多行,並可以對該行數據進行特定的操作。從而爲用戶在處理數據的過程提供很大方便。

3.2 遊標的基礎語法和示例

創建一個遊標
cursor 遊標名 [(參數名 數據類型)] is select語句
光標的遍歷
fetch 光標名 into 變量名
光標的屬性
-%found 如果至少影響到一行數據該屬性true,否則false
-%notfound 與found屬性相反
-%rowcount 返回受影響的行數
光標的使用過程
1 聲明光標
2 打開光標
3 讀取光標
4 關閉光標
示例:統計不同年份入職的員工人數

set serveroutput on
declare
--聲明遊標
cursor edate is select to_char(hiredate,'yyyy') from emp;
--爲遊標定義對應的變量
countyear varchar2(4);
--保存不同年份入職的員工數
count80 number:=0;
count81 number:=0;
count82 number:=0;
begin
--打開遊標
open edate;
loop
--取一條記錄賦給變量
fetch edate into countyear;
--取不到記錄時退出循環
exit when edate%notfound;
--根據不同年份統計計數
if countyear='1980' then  count80:=count80+1;
elsif countyear='1981' then  count81:=count81+1;
else count82:=count82+1;
end if;
end loop;
--關閉遊標
close edate;
dbms_output.put_line('1980年入職'||count80||'個');
dbms_output.put_line('1981年入職'||count81||'個');
dbms_output.put_line('1982年入職'||count82||'個');
end;

示例:查詢某個部門的員工姓名(帶參數的遊標)

set serveroutput on
declare
--創建一個遊標
cursor dcor(dno number) is select ename from emp where depno=dno;
--定義遊標對應變量
dname emp.ename%type;
begin
--打開遊標時傳入實參
open dcor(30);
loop
--遍歷遊標
fetch dcor into dname;
exit when dcor%notfound;
dbms_output.put_line(dname);
end loop;
close dcor;
end;

4 例外(異常)

例外是程序設計語言提供的一種功能,用來對程序發生異常時的處理,提高程序的健壯性和容錯性。
pl/sql異常處理代碼放在exception代碼塊中,通常包括預定義異常和自定義異常。
常見的預定義異常有:

  • No_data_found(沒有找到數據)
  • Too_many_rows(select …into語句匹配多行)
  • Zero_Divide(被零除)
  • Value_error(算術或轉換錯誤)
  • Timeout_on_resource(在等待資源時發生超時)

語法格式爲
begin
程序體
[exception]
異常處理語句
end;
實例:一個select語句匹配多行異常

set serveroutput on
declare
bname emp.ename%type;
begin
select ename into bname from emp where deptno=20;
exception
--異常類型,可以有多個
when Too_many_rows then dbms_output.put_line('匹配多行');
--其他異常
when others then dbms_output.put_line('其他異常');
end;

我們要儘可能的捕獲所有例外。實際開發中我們可能需要根據業務邏輯拋出一些自定義異常。用法:
在declare部分定義一個變量,類型爲exception.當需要拋出時用raise關鍵字,然後在exception中捕獲就好了。
示例:

set serveroutput on
declare 
cursor c_emp is select ename from emp where deptno=50;
p_ename emp.ename%type;
--定義一個例外
no_emp_found exception;
begin
open c_emp;
--獲取一條記錄
fetch c_emp into p_ename;
--如果沒有查到則拋出自定義例外
if c_emp%notfound then 
raise no_emp_found;
end if;
--此處,當前一句拋出例外執行完exception後,
--oracle會自動啓動一個pmon(process monitor)的一個進程
--將pl/sql程序中未關閉的資源釋放
--所以 close c_emp; 還是會執行的
close c_emp;
--捕獲例外
exception 
when no_emp_found then dbms_output.put_line('沒有該部門下的員工');
when others then dbms_output.put_line('其他例外');
end;
發佈了27 篇原創文章 · 獲贊 20 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章