PL/SQL 語句塊詳細解說
阿新 • • 發佈:2019-01-20
PL/SQL語言
作用:如果不使用PL/SQL語言,oracle一次只能處理一條SQL語句。每條SQL語句都導致客戶(client)向伺服器(server)呼叫,從而在效能上產生很大的開銷,尤其是在網路操作中。如果使用PL/SQL,一個塊中的語句作為一個組,導致客戶向伺服器的一次呼叫,減少網路轉輸
PL/SQL塊結構與用途
一個基本的PL/SQL塊由三部分組成:定義部分、可執行部分以及例外處理部分:
定義部分:
定義將在可執行部分中呼叫的所有變數、常量、遊標和使用者自定義的例外處理。這部分可以沒有。
可執行部分:
包括對資料庫中進行操作的SQL語句,以及對塊中進行組織、控制的PL/SQL語句。這部分必須存在。
例外處理部分:
對可執行部分中的語句,在執行過程中出錯或出現非正常現象時所做的相應處理。這部分可以沒有。
由基本的PL/SQL塊組成PL/SQL程式,可組成不同的程式形式,它們的用途和適用性各不相同。程式形式大致有以下幾種:
1、無名塊:也就是沒有命名的PL/SQL塊,它可以是嵌入某一個應用之中的一個PL/SQL塊。
2、儲存過程/函式:也就是命名了的PL/SQL塊,它可以接收引數,並且可以重複地被呼叫。
3、包
命名了的PL/SQL模組,由一組相關的過程、函式和識別符號組成。可以將任何出現在塊宣告的語句 ( 過程 , 函式 , 遊標 , 型別 , 變數 ) 放於包中 , 相當於一個容器 . 將宣告語句放入包中的好處是 : 使用者可以從其他 PL/SQL 塊中對其進行引用 , 因此包為 PL/SQL 提供了全程變數。
4、資料庫觸發器:是一個與具體資料庫表相關聯的儲存PL/SQL程式。每當一個SQL操作影響到該資料庫表時,系統就自動執行相應的資料庫觸發器。每個表最多可以有12個觸發器。
PL/SQL塊的定義部分
變數宣告語法:
識別符號 [constant] 資料型別 [not null]
[:=預設值或PL/SQL表示式]
注意的幾點(書p73):
加上關鍵字CONSTANT,則表示所定義的識別符號為一個常量,必須為它賦初值。
如果定義的識別符號不能為空,則必須加關鍵字NOT NULL,並賦初值。
“:=”為賦值操作符。
PL/SQL提供了SQL沒有的附加資料型別。除一般的ORACLE SQL資料型別外,PL/SQL還可以使用這些資料型別對變理進行說明
1、BOOLEAN:可用預定義的常量TRUE、FALSE或NULL對一個布林變數賦值。
2、binary_integer(二進位制整數):數值範圍在 -2,147,483,647到2,147,483,647之間。
3、NATURAL(自然數):數值範圍在0到2,147,483,647之間。
4、POSITIVE(正整數):數值範圍在1到2,147,483,647之間。
5、%TYPE:可說明一個變數的資料型別與某一指定列的資料型別相同。
6、%ROWTYPE: 用這種資料型別可以說明一個複合變數,與某一特定有中的一行相同。
變數宣告分標量型變數宣告和組合變數(複合變數)宣告。標量型變數是指其內部沒有成員的變數。
例:
age number(5) not null:=25;
pi constant number(9):=3.1415926;
name char(10) not null:=‘fan’;
today date not null:=sysdate;
sex boolean:=true;
例:宣告一個變數Student_name,其型別基於另一個變數teacher_name。
Teacher_name char(10);
Student_name teacher_name%type;
例: 宣告一個變數No,使其與表emp中EMPNO的型別一致。
no emp.empno%type;
組合型變數內部包含若干個成員,每個成員由標量型變數或組合型變數組成
定義組合型變數的語法如下:
type <型別名> is record
(<域名1> {<標量型資料型別> | <record型別>}[not null],
<域名2> {<標量型資料型別> | <record型別>}[not null],
…….);
<識別符號> <型別名>;
例:定義一個變數,存放一個學生的有關資訊。
declare
type student is record /*定義組合型變數型別*/
(id number(4) not null:=0,
name char(10) not null:=' ',
sex boolean not null:=true,
birthday date,
physics number(3),chemistry number(3));
stu student; /*定義組合型變數*/
begin
stu.id:=1;
stu.name:='sheng';
stu.sex:=true;
end;
例:宣告一個變數,其結構與表emp的資料結構相一致。
declare
emp_value emp%rowtype;
Begin
select * into empvalue from emp
where empno=7369;
dbms_output.put_line(‘姓名:’||‘ ’||emp_value.ename);
End;
注:在執行些PL/SQL塊前,應先執行
Set serveroutput on /*使dbms_output.put_line可以顯示在螢幕上*/
可執行部分
可執行部分可以包含變數賦值語句、資料查詢、資料操縱和事務控制語句。如select、insert、update、delete、commit、rollback等語句。而不能使用CREATE,ALTER,DROP,GRANT,REVOR等資料定義或資料控制命令。
給標量型變數賦值
teacher_name:=‘liu’;
給record型別變數賦值語法:
<record名.域名>:=<pl/sql表示式>;
例:
stud.name:=‘fan’ student.sex:=true;
%rowtype型變數的賦值與record相同。
例:計算表emp中所有僱員的平均工資。
declare
avg_sal number(7,2);
begin
select avg(sal) into avg_sal from emp;
dbms_output.put_line(‘平均工資為:’||avg_sal);
End;
在運用select語句查詢時注意查詢的結果只能有一條,如果返回的查詢結果多於一條或沒有找到任何資料,則會產生異常。
事務控制命令
一、事務的概念
事務是一個操作序列。這些操作要麼都做,要麼都不做,是一個不可分割的工作單位。事務通常以BEGIN TRANSACTION開始,以COMMIT或ROLLBACK操作結束,COMMIT即提交,提交事務中所有的操作、事務正常結束。ROLLBACK即撤消已作的所有操作,滾回到事務開始時的狀態。
二、事務提交命令
作用:提交自上次提交以後對資料庫中資料所作的改動。事務提交以後,這些操作就不能再撤消。
事務提交有3種方式:
1、顯式提交:使用commit命令
2、隱式提交:有些命令,如alter、audit、comment、connect、create、disconnect、
drop、exit、grant、noaudit、revoke、rename命令等都隱含有commit操作,而無須指明該操作。
3、自動提交
使用者可以使用set命令來設定自動提交環境。經過設定後,sql/plus會自動提出交使用者的更新工作。一旦設定了自動提交,使用者每次執行insert、update或delete命令,系統就會立即自動進行提交。
命令為:
set auto on
三、事務回退
作用:尚未提交的UPDATE,INSERT,DELETE操作,可以用事務回退命令回退,回退之後資料庫將回到上次COMMIT後的狀態。
命令: rollback
四、儲存點
作用:可以把一個事務劃分成若干部分,每一部分之間用一個儲存點分隔。
格式:
savepoint 儲存點名;
rollback to 儲存點名;
PL/SQL流程控制
主要有三種:
條件控制
迴圈控制
跳轉控制
有兩種形式:
1、 IF_THEN_ELSE語句
語法格式:
if 條件 then
語句1;
語句2;
…… else
語句n;
語句n+1;
…… end if;
2、IF_THEN_ELSE_IF語句
語法格式:
IF 條件1 THEN
語句1;
語句2;
……Elsif 條件2 THEN
語句3;
語句4;
[ELSIF 條件 n THEN
……]
[ELSE
語句n+1
……]
END IF
1、根據下式計算y值
x+1 x>3
y= X×2 X>=0
X÷3 X<0
PL/SQL實現語句1:
declare
x number(4);
y number(10,2);
begin
x:=&x; /* 實現從鍵盤輸入一個值給X */
if x>=3 then
y:=x+1;
elsif x>=0 then
y:=x*2;
else
y:=x/3;
end if;
dbms_output.put_line(y); /* 輸出Y值 */
end;
PL/SQL實現語句2:declare
x number(4);
y number(10,2);
begin
x:=&x;
if x>=3 then
y:=x+1;
else if x>=0 then
y:=x*2;
else
y:=x/3;
end if;
end if;
dbms_output.put_line(y);
end;
注意:條件語句中可以沒有else 語句如:
declare
x number(4);
y number(10,2);
begin
x:=&x;
if x>=3 then
y:=x+1;
end if;
dbms_output.put_line(y);
end;
迴圈控制語句
有四種類型:
FOR迴圈
直到型迴圈
當型迴圈
簡單迴圈
FOR迴圈
語法格式:
For 計數器 in [reverse] 下界..上界
Loop
語句1;
語句2;
……END LOOP;
注意:
計數器是有於控制迴圈資數的變數,它不需顯式地在變數定義部分進行定義。
系統預設時,計數器從下界往上界遞增記數,如果在關鍵字IN後加上REVERSE則表示計數器從上界到下界遞增記數。
計數器變數只能在迴圈體內部使用,不能在迴圈體外使用。
例:計算1+2+3+……+100的值
declare
S number(5):=0;
Begin
For I in 1..100
Loop
s:=s+I;
End loop;
Dbms_output.put_line(s);
End;
/
例4.10
從鍵盤接收一個整數,計算它的階乘並在螢幕上列印輸出。
declare
num number(3);
Fac number;
begin
Num:=&num
fac:=1;
if num>0 then
for i in 1..num loop
fac:=fac*i;
end loop;
end if;
end;
直到型迴圈
特點:先執行迴圈體,後判斷條件。
語法格式:
Loop
<語句1>
<……>
Exit [when 條件]
<語句 n>
<……>
End loop;
例4.11用直到型迴圈控制語句求從1-100所有整數的和。
解1: declare
I number(3):=100;
suma number;
begin
suma:=0;
loop
suma:=suma+I;
I:=I-1;
exit when I=0;
end loop;
end;
解2:
declare
I number(3):=1;
suma number;
begin
suma:=0;
loop
suma:=suma+I;
I:=I+1;
exit when I>100;
end loop;
dbms_output.put_line(suma);
end;
當型迴圈
特點:先判斷條件,後執行迴圈體。
語法格式:
While <條件> loop
<語句1>
<……>
End loop;
例4.12 採用當型迴圈控制語句求1-100所有整數的和
解:先申明一個全域性變數:
variable suma number
再寫PL/SQL塊:
declare
I number(3):=100;
begin
:suma:=0; /*變數suma前帶有“:”表示為全域性變數*/
While I>0 loop
:suma:=:suma+I;
I:=I-1;
End loop;
End;
跳轉語句
語法格式:
<<標號>>
……Goto 標號
有幾項原則:
可以實現同一塊中語句之間的跳轉
可以從子塊跳至父塊,但不能從父塊跳至子塊
不能從IF語句體外跳入IF語句內。
不能從迴圈體外跳入迴圈體內。
不能從子程式外部跳入到子程式內
迴圈語句的巢狀
即一個迴圈語句中還可以包括其它的迴圈語句。
例:求100-200間的全部素數。
declare
fag boolean:=true;
begin
for i in 100..200 loop
for j in 2..i-1 loop
if mod(i,j)=0 then
fag:=false;
end if;
end loop;
if fag then
dbms_output.put_line(i);
end if;
fag:=true;
end loop;
end;
PL/SQL允許在一個塊中包含子塊,下段程式中列出了一個匿名的塊,它包含另一個子塊,該子塊有自己的說明部分。例如:
declare
max_i constant int:=100;
i int:=1;
rec_number int ;
begin
for i in 1..max_i loop
if mod(i,5)=0 then
作用:如果不使用PL/SQL語言,oracle一次只能處理一條SQL語句。每條SQL語句都導致客戶(client)向伺服器(server)呼叫,從而在效能上產生很大的開銷,尤其是在網路操作中。如果使用PL/SQL,一個塊中的語句作為一個組,導致客戶向伺服器的一次呼叫,減少網路轉輸
PL/SQL塊結構與用途
一個基本的PL/SQL塊由三部分組成:定義部分、可執行部分以及例外處理部分:
定義部分:
定義將在可執行部分中呼叫的所有變數、常量、遊標和使用者自定義的例外處理。這部分可以沒有。
可執行部分:
包括對資料庫中進行操作的SQL語句,以及對塊中進行組織、控制的PL/SQL語句。這部分必須存在。
例外處理部分:
對可執行部分中的語句,在執行過程中出錯或出現非正常現象時所做的相應處理。這部分可以沒有。
由基本的PL/SQL塊組成PL/SQL程式,可組成不同的程式形式,它們的用途和適用性各不相同。程式形式大致有以下幾種:
1、無名塊:也就是沒有命名的PL/SQL塊,它可以是嵌入某一個應用之中的一個PL/SQL塊。
2、儲存過程/函式:也就是命名了的PL/SQL塊,它可以接收引數,並且可以重複地被呼叫。
3、包
命名了的PL/SQL模組,由一組相關的過程、函式和識別符號組成。可以將任何出現在塊宣告的語句 ( 過程 , 函式 , 遊標 , 型別 , 變數 ) 放於包中 , 相當於一個容器 . 將宣告語句放入包中的好處是 : 使用者可以從其他 PL/SQL 塊中對其進行引用 , 因此包為 PL/SQL 提供了全程變數。
4、資料庫觸發器:是一個與具體資料庫表相關聯的儲存PL/SQL程式。每當一個SQL操作影響到該資料庫表時,系統就自動執行相應的資料庫觸發器。每個表最多可以有12個觸發器。
PL/SQL塊的定義部分
變數宣告語法:
識別符號 [constant] 資料型別 [not null]
[:=預設值或PL/SQL表示式]
注意的幾點(書p73):
加上關鍵字CONSTANT,則表示所定義的識別符號為一個常量,必須為它賦初值。
如果定義的識別符號不能為空,則必須加關鍵字NOT NULL,並賦初值。
“:=”為賦值操作符。
PL/SQL提供了SQL沒有的附加資料型別。除一般的ORACLE SQL資料型別外,PL/SQL還可以使用這些資料型別對變理進行說明
1、BOOLEAN:可用預定義的常量TRUE、FALSE或NULL對一個布林變數賦值。
2、binary_integer(二進位制整數):數值範圍在 -2,147,483,647到2,147,483,647之間。
3、NATURAL(自然數):數值範圍在0到2,147,483,647之間。
4、POSITIVE(正整數):數值範圍在1到2,147,483,647之間。
5、%TYPE:可說明一個變數的資料型別與某一指定列的資料型別相同。
6、%ROWTYPE: 用這種資料型別可以說明一個複合變數,與某一特定有中的一行相同。
變數宣告分標量型變數宣告和組合變數(複合變數)宣告。標量型變數是指其內部沒有成員的變數。
例:
age number(5) not null:=25;
pi constant number(9):=3.1415926;
name char(10) not null:=‘fan’;
today date not null:=sysdate;
sex boolean:=true;
例:宣告一個變數Student_name,其型別基於另一個變數teacher_name。
Teacher_name char(10);
Student_name teacher_name%type;
例: 宣告一個變數No,使其與表emp中EMPNO的型別一致。
no emp.empno%type;
組合型變數內部包含若干個成員,每個成員由標量型變數或組合型變數組成
定義組合型變數的語法如下:
type <型別名> is record
(<域名1> {<標量型資料型別> | <record型別>}[not null],
<域名2> {<標量型資料型別> | <record型別>}[not null],
…….);
<識別符號> <型別名>;
例:定義一個變數,存放一個學生的有關資訊。
declare
type student is record /*定義組合型變數型別*/
(id number(4) not null:=0,
name char(10) not null:=' ',
sex boolean not null:=true,
birthday date,
physics number(3),chemistry number(3));
stu student; /*定義組合型變數*/
begin
stu.id:=1;
stu.name:='sheng';
stu.sex:=true;
end;
例:宣告一個變數,其結構與表emp的資料結構相一致。
declare
emp_value emp%rowtype;
Begin
select * into empvalue from emp
where empno=7369;
dbms_output.put_line(‘姓名:’||‘ ’||emp_value.ename);
End;
注:在執行些PL/SQL塊前,應先執行
Set serveroutput on /*使dbms_output.put_line可以顯示在螢幕上*/
可執行部分
可執行部分可以包含變數賦值語句、資料查詢、資料操縱和事務控制語句。如select、insert、update、delete、commit、rollback等語句。而不能使用CREATE,ALTER,DROP,GRANT,REVOR等資料定義或資料控制命令。
給標量型變數賦值
teacher_name:=‘liu’;
給record型別變數賦值語法:
<record名.域名>:=<pl/sql表示式>;
例:
stud.name:=‘fan’ student.sex:=true;
%rowtype型變數的賦值與record相同。
例:計算表emp中所有僱員的平均工資。
declare
avg_sal number(7,2);
begin
select avg(sal) into avg_sal from emp;
dbms_output.put_line(‘平均工資為:’||avg_sal);
End;
在運用select語句查詢時注意查詢的結果只能有一條,如果返回的查詢結果多於一條或沒有找到任何資料,則會產生異常。
事務控制命令
一、事務的概念
事務是一個操作序列。這些操作要麼都做,要麼都不做,是一個不可分割的工作單位。事務通常以BEGIN TRANSACTION開始,以COMMIT或ROLLBACK操作結束,COMMIT即提交,提交事務中所有的操作、事務正常結束。ROLLBACK即撤消已作的所有操作,滾回到事務開始時的狀態。
二、事務提交命令
作用:提交自上次提交以後對資料庫中資料所作的改動。事務提交以後,這些操作就不能再撤消。
事務提交有3種方式:
1、顯式提交:使用commit命令
2、隱式提交:有些命令,如alter、audit、comment、connect、create、disconnect、
drop、exit、grant、noaudit、revoke、rename命令等都隱含有commit操作,而無須指明該操作。
3、自動提交
使用者可以使用set命令來設定自動提交環境。經過設定後,sql/plus會自動提出交使用者的更新工作。一旦設定了自動提交,使用者每次執行insert、update或delete命令,系統就會立即自動進行提交。
命令為:
set auto on
三、事務回退
作用:尚未提交的UPDATE,INSERT,DELETE操作,可以用事務回退命令回退,回退之後資料庫將回到上次COMMIT後的狀態。
命令: rollback
四、儲存點
作用:可以把一個事務劃分成若干部分,每一部分之間用一個儲存點分隔。
格式:
savepoint 儲存點名;
rollback to 儲存點名;
PL/SQL流程控制
主要有三種:
條件控制
迴圈控制
跳轉控制
有兩種形式:
1、 IF_THEN_ELSE語句
語法格式:
if 條件 then
語句1;
語句2;
…… else
語句n;
語句n+1;
…… end if;
2、IF_THEN_ELSE_IF語句
語法格式:
IF 條件1 THEN
語句1;
語句2;
……Elsif 條件2 THEN
語句3;
語句4;
[ELSIF 條件 n THEN
……]
[ELSE
語句n+1
……]
END IF
1、根據下式計算y值
x+1 x>3
y= X×2 X>=0
X÷3 X<0
PL/SQL實現語句1:
declare
x number(4);
y number(10,2);
begin
x:=&x; /* 實現從鍵盤輸入一個值給X */
if x>=3 then
y:=x+1;
elsif x>=0 then
y:=x*2;
else
y:=x/3;
end if;
dbms_output.put_line(y); /* 輸出Y值 */
end;
PL/SQL實現語句2:declare
x number(4);
y number(10,2);
begin
x:=&x;
if x>=3 then
y:=x+1;
else if x>=0 then
y:=x*2;
else
y:=x/3;
end if;
end if;
dbms_output.put_line(y);
end;
注意:條件語句中可以沒有else 語句如:
declare
x number(4);
y number(10,2);
begin
x:=&x;
if x>=3 then
y:=x+1;
end if;
dbms_output.put_line(y);
end;
迴圈控制語句
有四種類型:
FOR迴圈
直到型迴圈
當型迴圈
簡單迴圈
FOR迴圈
語法格式:
For 計數器 in [reverse] 下界..上界
Loop
語句1;
語句2;
……END LOOP;
注意:
計數器是有於控制迴圈資數的變數,它不需顯式地在變數定義部分進行定義。
系統預設時,計數器從下界往上界遞增記數,如果在關鍵字IN後加上REVERSE則表示計數器從上界到下界遞增記數。
計數器變數只能在迴圈體內部使用,不能在迴圈體外使用。
例:計算1+2+3+……+100的值
declare
S number(5):=0;
Begin
For I in 1..100
Loop
s:=s+I;
End loop;
Dbms_output.put_line(s);
End;
/
例4.10
從鍵盤接收一個整數,計算它的階乘並在螢幕上列印輸出。
declare
num number(3);
Fac number;
begin
Num:=&num
fac:=1;
if num>0 then
for i in 1..num loop
fac:=fac*i;
end loop;
end if;
end;
直到型迴圈
特點:先執行迴圈體,後判斷條件。
語法格式:
Loop
<語句1>
<……>
Exit [when 條件]
<語句 n>
<……>
End loop;
例4.11用直到型迴圈控制語句求從1-100所有整數的和。
解1: declare
I number(3):=100;
suma number;
begin
suma:=0;
loop
suma:=suma+I;
I:=I-1;
exit when I=0;
end loop;
end;
解2:
declare
I number(3):=1;
suma number;
begin
suma:=0;
loop
suma:=suma+I;
I:=I+1;
exit when I>100;
end loop;
dbms_output.put_line(suma);
end;
當型迴圈
特點:先判斷條件,後執行迴圈體。
語法格式:
While <條件> loop
<語句1>
<……>
End loop;
例4.12 採用當型迴圈控制語句求1-100所有整數的和
解:先申明一個全域性變數:
variable suma number
再寫PL/SQL塊:
declare
I number(3):=100;
begin
:suma:=0; /*變數suma前帶有“:”表示為全域性變數*/
While I>0 loop
:suma:=:suma+I;
I:=I-1;
End loop;
End;
跳轉語句
語法格式:
<<標號>>
……Goto 標號
有幾項原則:
可以實現同一塊中語句之間的跳轉
可以從子塊跳至父塊,但不能從父塊跳至子塊
不能從IF語句體外跳入IF語句內。
不能從迴圈體外跳入迴圈體內。
不能從子程式外部跳入到子程式內
迴圈語句的巢狀
即一個迴圈語句中還可以包括其它的迴圈語句。
例:求100-200間的全部素數。
declare
fag boolean:=true;
begin
for i in 100..200 loop
for j in 2..i-1 loop
if mod(i,j)=0 then
fag:=false;
end if;
end loop;
if fag then
dbms_output.put_line(i);
end if;
fag:=true;
end loop;
end;
PL/SQL允許在一個塊中包含子塊,下段程式中列出了一個匿名的塊,它包含另一個子塊,該子塊有自己的說明部分。例如:
declare
max_i constant int:=100;
i int:=1;
rec_number int ;
begin
for i in 1..max_i loop
if mod(i,5)=0 then