plsql程式設計
阿新 • • 發佈:2019-02-11
此時emp_type只是宣告記錄型別,並不能直接用
(
var_ename varchar2(20),--定義欄位/成員變數
var_job varchar2(20),
var_sal number
);
empinfo emp_type;--定義變數 此時才能直接通過 . 來訪問
begin
select ename,job,sal
into empinfo
from emp where empno = 7369;--檢索資料
-- 輸出僱員資訊
dbms_output.put_line('僱員'||empinfo.var_ename||'的職務是'||empinfo.var_job||'、工資是'||empinfo.var_sal);
end;
3)%ROWTYPE型別:結合了%TYPE型別和RECORD型別變數的優點,它可以根據資料表中行的結構定義一種特殊的型別
用來儲存從資料表中檢索到的一行的資料。
rowVar_name table_name%rowtype;
rowVar_name:表示可以儲存一行資料的變數名
table_name:指定的表名
案例:
--宣告一個%ROWTYPE型別的變數rowVar_emp,然後使用該變數儲存emp表中的一行資料
declare
rowVar_emp emp%rowtype;--定義能夠儲存emp表中一行資料的變數 可以直接訪問
begin
select * into rowVar_emp
from emp
where empno = 7369;
dbms_output.put_line('僱員'||rowVar_emp.ename||'的編號是'||rowVar_emp.empno||',職務是'||rowVar_emp.job);
end;
五、定義變數和常量
1、定義變數
<變數名> <資料型別>[(長度):=<初始值>];
var_countryname varchar2(50):='中國';
2、定義常量
<常量名> constant<資料型別>:=<常量值>;
con_day constant integer:=365;
六、流程控制語句
1、選擇語句
1)if...then語句
if<condition_expression> then
plsql語句
end if;
案例:
-- if...then案例
declare
var_name1 varchar2(50);
var_name2 varchar2(50);
begin
var_name1:='East';
var_name2:='xiaoke';
if length(var_name1)<length(var_name2) then
dbms_output.put_line('字串'||var_name1||'的長度比字串'||var_name2||'的長度小');
end if;
end;
2)if..then...else
if<condition_expression> then
plsql語句
else
plsql語句
endif;
案例1:
-- if..then..else案例
declare
age int:=55;
begin
if age>=56 then
dbms_output.put_line('您可以申請退休了');
else
dbms_output.put_line('您小於56歲,不可以申請退休了!');
end if;
end;
3)if...then...elsif:實現多分支判斷選擇
if<conditon_expression1> then
plsql語句
elsif<condtion_expression2> 注意是elsif 而不是else if
plsql語句
else
plsql語句
end if;
案例1:
declare
month int:=10;--定義整型變數並賦值
begin
if month>=0and month<=3 then --判斷春季
dbms_output.put_line('這是春季');
elsif month>=4 and month<=6 then
dbms_output.put_line('這是夏季');
elsif month>=7and month<=9 then
dbms_output.put_line('這是秋季');
elsif month>=10 and month<=12 then
dbms_output.put_line('這是冬季');
else
dbms_output.put_line('對不起,月份不合法!');
end if;
end;
4)case語句
case<selector>
when <expression_1> then plsql語句1;
when <expression_2> then plsql語句2;
else
plsql語句;
end case;
案例:
-- case語句
declare
season int:=3;
aboutinfo varchar2(50);--儲存月份資訊
begin
case season --判斷季節
when 1 then
aboutinfo:=season||'季節包括1,2,3月份';
when 2 then
aboutinfo:=season||'季節包括4,5,6月份';
when 3 then
aboutinfo:=season||'季節包括7,8,9月份';
else
aboutinfo:=season||'季節不合法';
end case;
dbms_output.put_line(aboutinfo);
end;
2、迴圈結構
1)loop語句
loop loop和end loop 可理解為java中的“大括號”
plsql語句
exit when end_condition
end loop;
案例:
declare
sum_i int:=0;
i int:=0;
begin
loop
i:=i+1;
sum_i:=sum_i+i;
exit when i = 100;
end loop;
dbms_output.put_line('前100個自然數的和是:'||sum_i);
end;
2)while語句
while condition_expression loop
plsql語句
end loop;
案例:
--while語句
declare
sum_i int:=0;
i int:=0;
begin
while i<=99 loop
i:=i+1;
sum_i:=sum_i+i;
end loop;
dbms_output.put_line('前100個自然數的和是:'||sum_i);
end;
3)for語句
for variable_counter_name in [reverse] lower_limit..upper_limit loop reverse為反轉的意思
plsql語句
end loop;
variable_counter_name:表示一個變數,通常為整數型別,用來作為計數器
lower_limit:計數器的下限值
upper_limit:計數器的上限值
案例:
declare
sum_i int:=0;
begin
for i in reverse 1..100 loop
if mod(i,2)=0 then
sum_i:=sum_i+i;
end if;
end loop;
dbms_output.put_line('前100個自然數中偶數之和是:'||sum_i);
end;
============PL/SQL遊標===========
一、遊標的基本概念:
遊標提供了一種從表中檢索資料並進行操作的靈活手段,遊標主要用在伺服器上,處理由客戶端傳送給伺服器的SQL語句。
遊標的作用:就相當於指標,通過遊標PL/SQL程式可以一次處理查詢結果集中的一行
並可以對該行資料執行特定操作,從而為使用者在處理資料的過程中提供了很大方便。
遊標分類:通過遊標操作資料主要使用顯式遊標和隱式遊標
二、顯式遊標
概念:顯式遊標是由使用者宣告和操作的一種遊標,通常用於操作查詢結果集(即由select語句返回的查詢結果)
處理資料的步驟:
1)宣告遊標
cursor curname[input_parameter1,[,input_parameter2]]
[return ret_type]
is select_sentence;
cur_name:表示所宣告的遊標名稱
ret_type:表示執行遊標操作後的返回值型別
select_sentence:遊標所使用的select語句,它為遊標的反覆讀取提供結果集
input_parameter1:作為遊標的輸入引數,可以有多個
宣告一個遊標,用來讀取emp表中職務為銷售員(SALESMAN)的僱員資訊
declare
cursor cur_emp(var_job in varchar2:='SALESMAN')
is select empno,ename,sal
from emp
where job=var_iob;
2)開啟遊標
open cur_name(para_value1,[para_value2]...)
open cur_emp('MANAGER');
在開啟遊標過程中,程式首先將符合條件的記錄送入記憶體中,然後在將指標,指向第一條記錄。
3)讀取遊標
讀取遊標就是將結果集中的資料儲存到變數中,讀取遊標使用fetch..into
fetch cur_name into {variable}
4)關閉遊標
遊標使用完畢後需要關閉,以釋放系統資源
close cur_name
注意:讀取遊標可能是個反覆操作的步驟,因為遊標每次只能讀取一行資料,所以對於多條記錄
需要反覆讀取,直到遊標讀取不到資料為止。
--遊標案例
-- 宣告一個檢索emp表中僱員資訊的遊標,然後開啟遊標,並制定檢索職務是MANAGER的僱員資訊
--接著使用fetch..into語句和while迴圈讀取由表中的所有僱員資訊最後輸出讀取的僱員資訊
declare
/*宣告遊標,檢索僱員資訊*/
cursor cur_emp(var_job in varchar2:='SALESMAN')
is select empno,ename,sal
from emp where job=var_job;
type record_emp is record --宣告一個記錄型別
(
/*定義當前記錄的成員變數*/
var_empno emp.empno%type,
var_ename emp.ename%type,
var_sal emp.sal%type
);
emp_row record_emp;--宣告一個record_emp型別的變數
begin
open cur_emp('MANAGER');--開啟遊標
fetch cur_emp into emp_row;--先讓指標只想結果集中的第一行,並將值儲存到emp_row中
while cur_emp%found loop
dbms_output.put_line(emp_row.var_ename||'的編號是'||emp_row.var_empno||'的工資是'||emp_row.var_sal);
fetch cur_emp into emp_row;--讓指標只想結果集中的下一行,並將值儲存到emp_row中
end loop;
close cur_emp;--關閉遊標
end;
三、遊標屬性
無論是顯式遊標還是隱式遊標,都具有%found、%notfound、%isopen、%rowcount 4個屬性
%notfound fetch是否提到資料 沒有true 提到false
%found fetch是否提到資料 有true 沒提到false
%rowcount 返回sql語句影響的行數
%isopen 布林值 遊標是否開啟
--遊標屬性案例
--宣告一個遊標用於檢索指定員工編號的僱員資訊,然後使用遊標%found屬性來判斷是否檢索到指定員工編號的僱員資訊
declare
var_ename varchar2(50);--宣告變數,用來儲存僱員名稱
var_job varchar2(50);--宣告變數,用來儲存僱員的職務
/*宣告遊標檢索指定員工編號的僱員資訊*/
cursor cur_emp --定義遊標檢索指定編號的記錄資訊
is select ename,job
from emp
where empno=7499;
begin
open cur_emp;--開啟遊標
fetch cur_emp into var_ename,var_job;
if cur_emp%found then --若檢索到資料記錄,則輸出僱員資訊
--dbms_output.put_line('編號是7499的僱員名稱為:'||var_ename||',職務是:'+var_job);
dbms_output.put_line('編號是7499的僱員名稱為:'||var_ename||'的職務是:'||var_job);
else
dbms_output.put_line('無資料記錄');--提示無記錄資訊
end if;
end;
四、隱式遊標
在執行SQL語句時,Oracle會自動建立一個隱式遊標。這個遊標在記憶體中處理該語句的工作區域。
隱式遊標主要是處理資料操縱語句(UPDATE、DELETE語句)
由於隱式遊標也有屬性,當使用隱式遊標的屬性時,需要在屬性前面加上隱式遊標的預設名稱-SQL
--隱式遊標案例
--在SCOTT模式下,把emp表中銷售人員(即SALESMAN)的工資上調20%,然後使用隱式遊標sql的%rowcount屬性輸出上調工資的員工數量
begin
update emp
set sal = sal*(1+0.2)
where job = 'SALESMAN';
if sql%notfound then
dbms_output.put_line('沒有僱員需要上調工資');
else
dbms_output.put_line('有'||sql%rowcount||'個僱員工資上調20%');
end if;
end;
五、通過for語句循環遊標
for var_auto_record in cur_name loop
plsql語句
end loop;
var_auto_record:自動的RECORD型別的變數,可以是任意合法的變數名稱
cur_name:指定的遊標名稱
案例1:
-- 使用隱式遊標和for語句檢索出職務是銷售員的僱員資訊並輸出
begin
for emp_record in (select empno,ename,sal from emp where job='SALESMAN')
loop
dbms_output.put('僱員編號:'||emp_record.empno);
dbms_output.put(';僱員名稱:'||emp_record.ename);
dbms_output.put_line(';僱員工資:'||emp_record.sal);
end loop;
end;
案例2:
--使用顯式遊標和for語句檢索出部門編號是30的僱員資訊並輸出
declare
cursor cur_emp is
select * from emp
where deptno = 30;
begin
for emp_record in cur_emp
loop
dbms_output.put('僱員編號:'||emp_record.empno);
dbms_output.put('僱員名稱:'||emp_record.ename);
dbms_output.put_line('僱員職務:'||emp_record.job);
end loop;
end;
(
var_ename varchar2(20),--定義欄位/成員變數
var_job varchar2(20),
var_sal number
);
empinfo emp_type;--定義變數 此時才能直接通過 . 來訪問
begin
select ename,job,sal
into empinfo
from emp where empno = 7369;--檢索資料
-- 輸出僱員資訊
dbms_output.put_line('僱員'||empinfo.var_ename||'的職務是'||empinfo.var_job||'、工資是'||empinfo.var_sal);
end;
3)%ROWTYPE型別:結合了%TYPE型別和RECORD型別變數的優點,它可以根據資料表中行的結構定義一種特殊的型別
用來儲存從資料表中檢索到的一行的資料。
rowVar_name table_name%rowtype;
rowVar_name:表示可以儲存一行資料的變數名
table_name:指定的表名
案例:
--宣告一個%ROWTYPE型別的變數rowVar_emp,然後使用該變數儲存emp表中的一行資料
declare
rowVar_emp emp%rowtype;--定義能夠儲存emp表中一行資料的變數 可以直接訪問
begin
select * into rowVar_emp
from emp
where empno = 7369;
dbms_output.put_line('僱員'||rowVar_emp.ename||'的編號是'||rowVar_emp.empno||',職務是'||rowVar_emp.job);
end;
五、定義變數和常量
1、定義變數
<變數名> <資料型別>[(長度):=<初始值>];
var_countryname varchar2(50):='中國';
2、定義常量
<常量名> constant<資料型別>:=<常量值>;
con_day constant integer:=365;
六、流程控制語句
1、選擇語句
1)if...then語句
if<condition_expression> then
plsql語句
end if;
案例:
-- if...then案例
declare
var_name1 varchar2(50);
var_name2 varchar2(50);
begin
var_name1:='East';
var_name2:='xiaoke';
if length(var_name1)<length(var_name2) then
dbms_output.put_line('字串'||var_name1||'的長度比字串'||var_name2||'的長度小');
end if;
end;
2)if..then...else
if<condition_expression> then
plsql語句
else
plsql語句
endif;
案例1:
-- if..then..else案例
declare
age int:=55;
begin
if age>=56 then
dbms_output.put_line('您可以申請退休了');
else
dbms_output.put_line('您小於56歲,不可以申請退休了!');
end if;
end;
3)if...then...elsif:實現多分支判斷選擇
if<conditon_expression1> then
plsql語句
elsif<condtion_expression2> 注意是elsif 而不是else if
plsql語句
else
plsql語句
end if;
案例1:
declare
month int:=10;--定義整型變數並賦值
begin
if month>=0and month<=3 then --判斷春季
dbms_output.put_line('這是春季');
elsif month>=4 and month<=6 then
dbms_output.put_line('這是夏季');
elsif month>=7and month<=9 then
dbms_output.put_line('這是秋季');
elsif month>=10 and month<=12 then
dbms_output.put_line('這是冬季');
else
dbms_output.put_line('對不起,月份不合法!');
end if;
end;
4)case語句
case<selector>
when <expression_1> then plsql語句1;
when <expression_2> then plsql語句2;
else
plsql語句;
end case;
案例:
-- case語句
declare
season int:=3;
aboutinfo varchar2(50);--儲存月份資訊
begin
case season --判斷季節
when 1 then
aboutinfo:=season||'季節包括1,2,3月份';
when 2 then
aboutinfo:=season||'季節包括4,5,6月份';
when 3 then
aboutinfo:=season||'季節包括7,8,9月份';
else
aboutinfo:=season||'季節不合法';
end case;
dbms_output.put_line(aboutinfo);
end;
2、迴圈結構
1)loop語句
loop loop和end loop 可理解為java中的“大括號”
plsql語句
exit when end_condition
end loop;
案例:
declare
sum_i int:=0;
i int:=0;
begin
loop
i:=i+1;
sum_i:=sum_i+i;
exit when i = 100;
end loop;
dbms_output.put_line('前100個自然數的和是:'||sum_i);
end;
2)while語句
while condition_expression loop
plsql語句
end loop;
案例:
--while語句
declare
sum_i int:=0;
i int:=0;
begin
while i<=99 loop
i:=i+1;
sum_i:=sum_i+i;
end loop;
dbms_output.put_line('前100個自然數的和是:'||sum_i);
end;
3)for語句
for variable_counter_name in [reverse] lower_limit..upper_limit loop reverse為反轉的意思
plsql語句
end loop;
variable_counter_name:表示一個變數,通常為整數型別,用來作為計數器
lower_limit:計數器的下限值
upper_limit:計數器的上限值
案例:
declare
sum_i int:=0;
begin
for i in reverse 1..100 loop
if mod(i,2)=0 then
sum_i:=sum_i+i;
end if;
end loop;
dbms_output.put_line('前100個自然數中偶數之和是:'||sum_i);
end;
============PL/SQL遊標===========
一、遊標的基本概念:
遊標提供了一種從表中檢索資料並進行操作的靈活手段,遊標主要用在伺服器上,處理由客戶端傳送給伺服器的SQL語句。
遊標的作用:就相當於指標,通過遊標PL/SQL程式可以一次處理查詢結果集中的一行
並可以對該行資料執行特定操作,從而為使用者在處理資料的過程中提供了很大方便。
遊標分類:通過遊標操作資料主要使用顯式遊標和隱式遊標
二、顯式遊標
概念:顯式遊標是由使用者宣告和操作的一種遊標,通常用於操作查詢結果集(即由select語句返回的查詢結果)
處理資料的步驟:
1)宣告遊標
cursor curname[input_parameter1,[,input_parameter2]]
[return ret_type]
is select_sentence;
cur_name:表示所宣告的遊標名稱
ret_type:表示執行遊標操作後的返回值型別
select_sentence:遊標所使用的select語句,它為遊標的反覆讀取提供結果集
input_parameter1:作為遊標的輸入引數,可以有多個
宣告一個遊標,用來讀取emp表中職務為銷售員(SALESMAN)的僱員資訊
declare
cursor cur_emp(var_job in varchar2:='SALESMAN')
is select empno,ename,sal
from emp
where job=var_iob;
2)開啟遊標
open cur_name(para_value1,[para_value2]...)
open cur_emp('MANAGER');
在開啟遊標過程中,程式首先將符合條件的記錄送入記憶體中,然後在將指標,指向第一條記錄。
3)讀取遊標
讀取遊標就是將結果集中的資料儲存到變數中,讀取遊標使用fetch..into
fetch cur_name into {variable}
4)關閉遊標
遊標使用完畢後需要關閉,以釋放系統資源
close cur_name
注意:讀取遊標可能是個反覆操作的步驟,因為遊標每次只能讀取一行資料,所以對於多條記錄
需要反覆讀取,直到遊標讀取不到資料為止。
--遊標案例
-- 宣告一個檢索emp表中僱員資訊的遊標,然後開啟遊標,並制定檢索職務是MANAGER的僱員資訊
--接著使用fetch..into語句和while迴圈讀取由表中的所有僱員資訊最後輸出讀取的僱員資訊
declare
/*宣告遊標,檢索僱員資訊*/
cursor cur_emp(var_job in varchar2:='SALESMAN')
is select empno,ename,sal
from emp where job=var_job;
type record_emp is record --宣告一個記錄型別
(
/*定義當前記錄的成員變數*/
var_empno emp.empno%type,
var_ename emp.ename%type,
var_sal emp.sal%type
);
emp_row record_emp;--宣告一個record_emp型別的變數
begin
open cur_emp('MANAGER');--開啟遊標
fetch cur_emp into emp_row;--先讓指標只想結果集中的第一行,並將值儲存到emp_row中
while cur_emp%found loop
dbms_output.put_line(emp_row.var_ename||'的編號是'||emp_row.var_empno||'的工資是'||emp_row.var_sal);
fetch cur_emp into emp_row;--讓指標只想結果集中的下一行,並將值儲存到emp_row中
end loop;
close cur_emp;--關閉遊標
end;
三、遊標屬性
無論是顯式遊標還是隱式遊標,都具有%found、%notfound、%isopen、%rowcount 4個屬性
%notfound fetch是否提到資料 沒有true 提到false
%found fetch是否提到資料 有true 沒提到false
%rowcount 返回sql語句影響的行數
%isopen 布林值 遊標是否開啟
--遊標屬性案例
--宣告一個遊標用於檢索指定員工編號的僱員資訊,然後使用遊標%found屬性來判斷是否檢索到指定員工編號的僱員資訊
declare
var_ename varchar2(50);--宣告變數,用來儲存僱員名稱
var_job varchar2(50);--宣告變數,用來儲存僱員的職務
/*宣告遊標檢索指定員工編號的僱員資訊*/
cursor cur_emp --定義遊標檢索指定編號的記錄資訊
is select ename,job
from emp
where empno=7499;
begin
open cur_emp;--開啟遊標
fetch cur_emp into var_ename,var_job;
if cur_emp%found then --若檢索到資料記錄,則輸出僱員資訊
--dbms_output.put_line('編號是7499的僱員名稱為:'||var_ename||',職務是:'+var_job);
dbms_output.put_line('編號是7499的僱員名稱為:'||var_ename||'的職務是:'||var_job);
else
dbms_output.put_line('無資料記錄');--提示無記錄資訊
end if;
end;
四、隱式遊標
在執行SQL語句時,Oracle會自動建立一個隱式遊標。這個遊標在記憶體中處理該語句的工作區域。
隱式遊標主要是處理資料操縱語句(UPDATE、DELETE語句)
由於隱式遊標也有屬性,當使用隱式遊標的屬性時,需要在屬性前面加上隱式遊標的預設名稱-SQL
--隱式遊標案例
--在SCOTT模式下,把emp表中銷售人員(即SALESMAN)的工資上調20%,然後使用隱式遊標sql的%rowcount屬性輸出上調工資的員工數量
begin
update emp
set sal = sal*(1+0.2)
where job = 'SALESMAN';
if sql%notfound then
dbms_output.put_line('沒有僱員需要上調工資');
else
dbms_output.put_line('有'||sql%rowcount||'個僱員工資上調20%');
end if;
end;
五、通過for語句循環遊標
for var_auto_record in cur_name loop
plsql語句
end loop;
var_auto_record:自動的RECORD型別的變數,可以是任意合法的變數名稱
cur_name:指定的遊標名稱
案例1:
-- 使用隱式遊標和for語句檢索出職務是銷售員的僱員資訊並輸出
begin
for emp_record in (select empno,ename,sal from emp where job='SALESMAN')
loop
dbms_output.put('僱員編號:'||emp_record.empno);
dbms_output.put(';僱員名稱:'||emp_record.ename);
dbms_output.put_line(';僱員工資:'||emp_record.sal);
end loop;
end;
案例2:
--使用顯式遊標和for語句檢索出部門編號是30的僱員資訊並輸出
declare
cursor cur_emp is
select * from emp
where deptno = 30;
begin
for emp_record in cur_emp
loop
dbms_output.put('僱員編號:'||emp_record.empno);
dbms_output.put('僱員名稱:'||emp_record.ename);
dbms_output.put_line('僱員職務:'||emp_record.job);
end loop;
end;