plsql實例精講部分筆記


 

轉換sql:  

 

create or replace view v_sale(year,month1,month2,month3,month4,month5,month6,month7,month8,month9,month10,month11,month12)

  as

  select

  substrb(month,1,4),

  sum(decode(substrb(month,5,2),'01',sell,0)),

  sum(decode(substrb(month,5,2),'02',sell,0)),

  sum(decode(substrb(month,5,2),'03',sell,0)),

  sum(decode(substrb(month,5,2),'04',sell,0)),

 

 

 

 

DECLARE

         STATEMENTS

BEGIN

         STATEMENTS

EXCEPTION

         STATEMENTS

END;

可執行部分必須存在

 

DECLARE

  v_first_name VARCHAR2(35);

  v_last_name  VARCHAR2(35);

  c_count CONSTANT NUMBER := 0;

BEGIN

  SELECT first_name, last_name

    INTO v_first_name, v_last_name

    FROM student

  WHERE student_id=123;

 

  DBMS_OUTPUT.PUT_LINE('student_name: ' || v_first_name || '  ' || v_last_name);

EXCEPTION

  WHEN NO_DATA_FOUND THEN

    DBMS_OUTPUT.PUT_LINE('There is no student with' || ' student id 123');

END;

 

PLSQL減少訪問數據庫的網絡傳輸

 

命名語句塊存儲在數據庫中,以后可以應用

 

DECLARE

    v_name VARCHAR2(50);

    v_total NUMBER;

BEGIN

    SELECT i.first_name || ' ' || i.last_name, COUNT(*)

           INTO v_name, v_toal

           FROM instructor i, section s

    WHERE i.instructor_id = s.instructor_id

          AND i.instructor_id = 123

    GROUP BY i.first_name || ' ' || i.last_name;                  

EXCEPTION

    WHEN NO_DATA_FOUND THEN

         DBMS_OUTPUT.put_line('There is no such instructor');

END; 

編譯過程: 語法檢查, 綁定(變量分配存儲地址), 生成偽代碼

 

. plsql結尾(可選)  /執行plsql 

 

set serveroutput on;顯示輸出結果 

 

 & 或者 && 替代變量前綴

使用替代變量獲取輸入值

替代變量沒有分配內存,不能用作輸出

 

 

& 每次出現替代變量都要重新輸入參數

  

set verify off; 不顯示具體替換工程

 

 

出現多次  && 只需輸入一次參數值   加上 ‘’

 

set define character  修改&為其他字符

set define on 重新修改為&

 

set serveroutput on size 5000; 修改默認緩存大小為5000字節

 

 

7一些函數類型

聲明變量如果沒有賦值    則為null,dbms_output輸出時內容為空

|| 不要用空格

 

coalesce(sum(data) , null,0) 返回第一個不是null的值

 

nvl(sum(data),0)   oracle     ifnull(sum(data),0) mysql

 

decode(sign(salary-8000),1,salary*1.15,-1,salary*1.2,salary)   sign(data) 返回-1  1  0

 

to_char(34.56,’fm999.00’)  34.56

to_char(0.123,’fm999.00’)  .12

9沒有數字顯示空格,0沒有數字顯示0 。fm去掉如果是9顯示的空格。

to_char(0.123,’fm990.00’)

 

TO_NUMBER(REGEXP_REPLACE(status,'[^0-9]','')) > 30

status中非數字轉換為空字符 在用to_number函數

select to_number(’RMB234234.4350′,’L999999.0000′) from dual;

 

 

select username,decode(lock_date,null,'unlocked','locked') status from t;

anchroed數據類型

declare

       v_name sys_user.usr_name%type;

 

字節  字符

varchar2(n) 與字節數有關,a 1b 我2b   varchar2(n char) 與字符數有關   a 1一個字符   哦 1個字符    每個字符占2個字節

nvarchar(n) 與字符數有關  可以容納n個字符  每個字符2個字節

 

varchar2(n)   number(m,n) 四舍五入

date  timestamp  binary_integer 用於索引plsql表    boolean一般用char(1)

oracle 沒有Boolean    plsql有Boolean   輸出不能直接用Boolean類型值

 

函數:trunc(sysdate, ‘hh24’) 2013-01-06 17:00:00  trunc(124.235,2) 124.23

 

to_char(sysdate, ‘hh24’) 17     sysdate+numtodsinterval(30,’minute’)

substr  instr  trunk    to_date to_timestamp

 

date相減是天數(帶小數)  timestamp相減是時間格式

timestamp精確到毫秒

trunc不支持timestamp

 

聲明exception變量    e_show_exception_scope exception;  raise exception拋出異常

when e_show_exception_show then ….

《inner_block》《outer_block》

 

v_bool  Boolean;   null  true  false

if v_bool is null then… end;

v_bool := nvl(v_bool , false);

if(v_bool) then dbms_output.put_line(‘false’);

 

sequence.currval   nextval

dml

select into

commit rollback   savepoint xx     rollback to savepoint xxx

 

 

trim  ltrim rtrim

8條件語句

if then else end if

if   then    elseif  then   else  end if

 

case  搜索case  表達式case  3種形式

 

case xxx類型  與when xx返回類型一樣

case xxx   when  xx then  xx;  when xxx then xx ;  else xx;  end case;

搜索case   when返回Boolean類型值

case       when xxx  then xx ; else xx; end case;

表達式case 

賦值:=case   end

select  case。。。end   into

表達式case  直接end,不是end case   表達式case中沒有 符號 ;

 

嵌套case

 

v_date date:=to_date(&sv_date,'yyyy-mon-dd');
to_char(v_date,'d')  數字形式星期  1234567  日一二三四五六七

 

nullif(exp1,exp2)  exp1=exp2返回null,否則返回exp1
exp1不能賦值字面值null

 

coalesce(exp1,exp2,exp3,…) 返回第一個不是null的值

 

9循環

loop  …  end loop

 

if xx then exit  end if

exit  when  condition

 

while condition  loop

statements

end loop

 

null不能與任何變量進行比較 false

 

循環計數器經常使用  binary_integer

 

for  v_counter in 1..5 loop statements  end loop

for中v_counter被隱含定義和 遞增,for外面不能引用v_counter

 

for v_counter in reverse 1..5 loop  exit when .. end loop

reverse逆序

 

if  then  continue end if;

continue when

10異常

exception when   then

no_data_found to_many_rows  zero_divide  login_denied  program_error

value_error invalid_number  dup_value_on_index

 

others

when others then …..

 

 

 

聲明部分的異常無法處理,除非外面還有語句塊包圍處理,

重新拋出  when  exception   then  raise

raise_application_error(-20001,’zip code is not valid’);

 

11游標

 

 

 

創建游標   打開游標  檢索游標  關閉游標

 

 

 

 

 

記錄類型

 

 

 

 

游標屬性: %notfound  %found  %isopen  %rowcount

sql%rowcount 隱藏游標可以用   沒有數據拋異常 不用sql%rowcount=0判斷

 

12.高級游標

 

 

 

 

 

 

 

 

 

或者open 時帶參數

 

 

會加鎖

 

 

13.觸發器

 

 

for each row 之能增刪改操作

 

刪除一個表,表上的觸發器也會刪除

使用:

一些復雜業務規則;統計值;自動生成衍生列的值;防止無效事務

事務回滾或者提交,觸發器執行的操作也會提交或者回滾。 自治事務例外

自治事務都會提交   autononous transaction   commit

 

:new   :old

 

 

 

 

 

 

 

 

 

如果某行沒有update,:new是null,所以用nvl(new.zip,’’)

 

 

 

 

 

操作view,底層數據庫表也會修改

 

 

 

 

 

刪除時如果存在約束,需要先刪除外鍵表中記錄

instead of 觸發器比較復雜,要考慮不同表之間的關系,以及特定關系可能引起的負面影響

 

 

 

視圖中插入數據時,外鍵zip在zipcode表中不存在對應記錄,則先在zipcode表中插入對應記錄

 

14.復合觸發器

變異表問題:

 

 

select into 操作的表section正在被修改,是變異的,改用如下方式:

 

 

 

 

 

 

 

 

復合觸發器:

 

 

 

 

 

 

 

 

 

 

drop trigger sss

drop package xxx

 

GRANT EXECUTE ON verify_function_11G TO PUBLIC;

 

 

 

 

 

 

before each row  才能用 :new

 

 

 

作業1:

create or replace trigger instructor_compound

for insert or update on instructor

compound trigger

  v_day varchar2(10);

  v_hour varchar2(5);

 

before statement is

begin

  v_day := rtrim(to_char(sysdate,'day'));

  v_hour := to_char(sysdate,'hh24');

 

  if v_day like ('s%') then

    raise_application_error(-20001,'this table can not be

     modified on off day');

  elseif v_hour <9 or v_hour >17 then

    raise_application_error(-20001,'this table can not be

     modified on off day');

  end if;

end before statement;

 

before each row is

begin

  :new.instructor_id := seq_instructor_id.nextval;

  if inserting then

    :new.created_by := user;

    :new.created_date := sysdate;

  elseif updating then

    :new.created_by := :old.created_by;

    :new.created_date := :old.created_date;

  end if;

  :new.modified_by := user;

  :new.modified_date := sysdate;

end before each row;

end instructor_compound;

 

作業2:

 

create or replace trigger zipcode_compound

for insert or update on zipcode

  v_type varchar2(10);

  v_count number;

  v_table varchar2(20);

before each row is

begin

  :new.modified_by := user;

  :new.modified_date := sysdate;

end before each row;

after statement is

 if inserting then

   v_type := 'insert';

 else updating then

   v_type := 'update';

 end if;

 

 v_count := sql%rowcount;

 v_table := 'zipcode';

 update zipcode

  set transaction_user=user,

      transaction_date=sysdate,

      transaction_rowcount=v_count

  where table_name = v_table

      and trancaction_name=v_type;

 

  if sql%notfound then

    insert into transaction

     values(v_table,v_type,user,sysdate,v_count);

  end if;

end after statement;

end zipcodecompound;

 

15章:集合

1.pl/sql表

聯合數組和嵌套表類似數據庫單列表,通過下標訪問,具有相同結構。

差別:嵌套表可以存儲在數據庫列中,聯合數組不可以。

聯合數組:

 

 

嵌套表:

 

要初始化,否則報異常 構造方法()

長度要擴展 extend

 

 

 

 

delete(10)  delete(1,3)  prior(3)  next(3)   trim(2)

count  last  first extend  trim

 

 

declare

  type index_by_type is table of number

    index by binary_integer;

  index_by_table index_by_type;

  type nested_type is table of number;

  nested_table nested_type :=

     nested_type(1,2,3,4,5,6,7,8,9,10);

begin

  for i in 1..10 loop

    index_by_table(i) := i;

  end loop;

 

  if index_by_table.exists(3) then

    dbms_output.put_line('index_by_table(3)='||

      index_by_table(3));

  end if;

 

  --delete 10th element from a collection

   nested_table.delete(10);

   --delete elements 1 through 3 from a colleciton

   nested_table.delete(1,3);

   index_by_table.delete(10);  

 

  dbms_output.put_line('nested_table.count='||nested_table.count);

  dbms_output.put_line('nested_table.first='||nested_table.first);

  dbms_output.put_line('nested_table.last='||nested_table.last);

  dbms_output.put_line('nested_table.prior(2)='||nested_table.prior(2));

  dbms_output.put_line('nested_table.next(2)='||nested_table.next(2));

 

  dbms_output.put_line('index_by_table.count='||index_by_table.count);

  dbms_output.put_line('index_by_table.first='||index_by_table.first);

  dbms_output.put_line('index_by_table.last='||index_by_table.last);

  dbms_output.put_line('index_by_table.prior(2)='||index_by_table.prior(2));

  dbms_output.put_line('index_by_table.next(2)='||index_by_table.next(2));

 

  nested_table.trim(2);

  dbms_output.put_line('nested_table.count='||nested_table.count);

  nested_table.trim();

  dbms_output.put_line('nested_table.count='||nested_table.count);

end;

 

 

當從中間刪除元素時,delete保留刪除元素的索引,則 count和last值就會不同。

 

last會比count值大

 

 

 

 

trim長度會改變,重新賦值需要 exntend

 

 

變長數組:

 

變長數組擴展不能超過最大尺寸,否則報錯。

 

extend(2,4) 末尾追加第四個元素的2個副本

 

limit限制長度

 

 

 

 

 

varray 變長數組不能delete

 

chr(10)換行

 

 

 

多層數組:

 

 

 

 

 

 

 

 

16記錄類型

 

 

 

type  xxx  is record (name  type,…)

%rowtype

 

 

 

not  null需要初始化,否則報錯

 

 

 

如果都是用戶自定義類型record ,如果類型名不同不可以相互賦值, 表記錄或者游標自定義類型之間可以相互賦值。

 

 

 

如果輸入內容較多,修改大小

 

 

17章  本地動態sql

 

 

 

例子:

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

18章 批量sql

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

2.indices of 可以處理稀疏的集合,嵌套表或者聯合數組。

 

 

 

 

 

3 values of 集合中元素做索引

 

 

 

 

創建一個有字段的空表

 

 

 

 

 

 

cursor要一行行檢索   

select  buck collect into  會批量檢索  直接講結果存保存在了集合中

 

 

 

 

1.select bulk collect into填充嵌套表時,會自動初始化和擴展。

2.bulk collect into select不返回任何數據時,不拋出no_data_found異常,所以要自己檢查返回的集合是否有數據。

3.bulk collect 不會限制集合的尺寸,並自動擴展,所以當select返回大量數據時,最好限制結合寄過集。  通過使用帶有游標select的bulk collect,以及添加limit.

 

帶有limit的bulk collect子句,一次性從student檢索50行數據。每個集合最多50條記錄。

 

 

 

 

 

合並forall  select bulk collect into

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM