1. 程式人生 > >plsql程式設計

plsql程式設計

 此時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;