oracle存儲過程學習


存儲過程學習1- 無參存儲過程

1 存儲過程定義:
一組為了完成特定功能的 PL/SQL 語句集,存儲在數據庫中,
經過第一次編譯后再次調用不需要再次編譯,用戶通過指定存儲過程的名字並給出參數(如果該存儲過程帶有參數)來執行它。
存儲過程是數據庫中的一個重要對象。

2 存儲過程優點:

  1. 可維護性高
    2)簡化操作流程

3 存儲過程缺點
1)數據庫移植不方便

4 hello world

create or replace procedure pro_test_demo
iS
begin
dbms_output.put_line('hello world')
end;
創建存儲過程,進行編譯,編譯成功后會在Procedure看到結果。

5 運行存儲過程

begin
pro_test_demo;
end;

存儲過程學習2-有參存儲過程

1 定義
create or replace procedure pro_with_params(v_a integer, v_b varchar2(36))
is
begin
dbms_output.put_line('第一個參數是:' || v_a);
end;
-- 和c類似, 參數類型寫在后面

2 執行
begin
execute pro_with_params(1, 'abd');
end;

存儲過程學習3-有輸出參數的存儲過程

1 定義
create or replace procedure pro_with_out_params(v_in_a in integer, v_out_b out varchar2)
is
begin

b:= 'abdd';
dbms_output.put_line('輸入參數:' || a);
end;

2 執行

declare i varchar2(36);
begin
pro_with_out_params(1, i);
dbms_output.put_line('輸出參數:' || i);
end;

注:存儲過程括弧里面定義varchar時不需要長度,但在declare定義時必須要有長度。

存儲過程學習4-存儲過程變量%TYPE

1 存儲過程中的變量類型:
1)標量類型
2)復合類型:記錄類型,索引表類型(關聯數組), varry變長數組

2 標量類型

常用的:NUMBER、CHAR 、VARCHAR2 、VARCHAR、NCHAR 、NVARCHAR2 、LONG 、DATE 、TIMESTAMP

3 %TYPE

%TYPE這種定義方式的變量類型, 利用已經存在的數據類型來定義新數據的數據類型,如定義多個變量或常量時,主要前面使用過的數據類型,后面的變量
可以利用%TYPE引用。

sex LY_DS.LY_NB%TYPE, 表示:定義一個變量sex, 它的數據類型與表LY_DS中的字段LY_NB類型一致

create or replace procedure test_select_procedure(
project PCA_PROJECT.NAME%TYPE, countNum out number)
is
begin
select count(*) into countNum from pca_project where name=project_name;
end;

存儲過程學習5 -- 記錄類型 %ROWTYPE

有一種場景:select多列,除了使用into的方法,還有另外一種引用名稱.引用成員
先來into的寫法
select count(*), max(id) into countNum, maxId from pca_project where id= 'ad';

如果是要獲取多列的結果呢,into不合適。記錄類型就是解決這個問題的。

1)type的聲明方法
格式:type type_name is recored(col_name, col_type);
括號可多列,以逗號隔開。

declare
TYPE new_type IS RECORD -- 這是聲明一種變量類型
(
v_project_name PCA_PROJECT.PROJECT_NAME%TYPE,
v_project_id PCA_PROJECT.PROJECT_ID%TYPE
);

v_obj new_type; -- 使用這種變量類型聲明一個變量v_obj

BEGIN
select project_name, project_id into v_obj from pca_project where id='ss';
END;

2 %ROWTYPE的聲明方法
%ROWTYPE, 該類型是提取行記錄時常用的存儲數據的方式。優點都是,避免表中字段數據類型改變,導致pl/sql塊出錯。

declare
v_obj pca_project%ROWTYPE;
BEGIN
select * into v_obj from pca_project where id='sdf';
dbms_output.put_line('第一個變量' || v_obj.name);
dbms_output.put_line('第二個變量' || v_obj.id);
END;

into前邊最好為*, 否則就要將所有字段寫全。

存儲過程學習6-關聯數組(索引表類型)

與數組類型,關聯數組利用鍵值查找對應的數據。不同是,鍵值和數組的下標只為整數不一樣,鍵值可為字符串。

1type自定義類型

1) 聲明一個存儲pca_project整行數據的索引表,下標為數字(binary_integer)
type index_row_type is table of pca_project%TYPE index by binary_integer;

2) 聲明一個存儲字符串數據的索引表,下標為數字
type index_varchar_type is table of varchar2(36) index by binary_integer;

3) 聲明一個存儲字符串數據的索引表,下標為字符串
type index_str_type is table of varchar(100) index by varchar(10);

2 利用自定義的索引表,定義變量

1) 聲明一個下標為數字, 值為pca_project整行數據的變量
v_row index_row_type;

2) 聲明一個下標為數字, 值為字符串的變量
v_var index_varchar_type;

3) 聲明一個下標為字符串,值為字符串的變量
v_str_val index_str_type;

3 索引表賦值

和字典一樣

  1. select * into v_row(1) from pca_project where id ='1';
  2. v_var(1) := '正數'; v_var(-1) := '負數'
  3. v_str_val('liuzhipeng') := '100分';

存儲過程學習7-變長數組

1)聲明

type array_type is varray(100) of varchar(100);

聲明一個最多容納100個元素的數組,每個元素類型為varchar(100), 下標從1開始,不是0;

  1. 定義變量

v_array array_type := array_type('one', 'two');

v_array2 array_type := array_type();

v_array2 array_type := array_type();
3) 獲取第一個元素

v_array(1)

4)為數組擴展下一個空位

v_array2.extend;
v_array2(1) := 'hello';
v_array2.extend;
v_array2(2) := 'world';

  1. 為數組初始化長度

v_array3.extend(v_array2.count());

v_array3.extend(4);

存儲過程學習8-簡單增刪改查sql

1 調用存儲過程的方法

1) begin end內
begin
pro_test_demo;
pro_with_params(1);
end;

2)execute執行
execute pro_test_demo;
execute pro_with_params(1);

  1. call
    call pro_test_demo;
    call pro_with_out_params(1);

2 查詢
create or replace procedure test_select2_procedure
(sex varchar)
AS
countNum number(10); --別忘了寫上具體的長度,並且以分號結束
maxId number(10); --別忘了寫上具體的長度,並且以分號結束
BEGIN
select count(*),max(id) into countNum,maxId from ly_ds where LY_NB=sex;
dbms_output.put_line(countNum);
dbms_output.put_line(maxId);
END;

3 插入 insert into
create or replace procedure test_add_procedure
(id varchar,createtime varchar,name varchar,
age varchar,sex varchar)
AS
BEGIN
insert into ly_ds values(id,createtime,name,age,sex);
commit; --別忘了加提交
end;

4 update

create or replace procedure test_update_procedure
(dsId varchar,mc varchar)
AS
BEGIN
update ly_ds set ly_mc = mc where id = dsId ;
commit; --別忘了加提交
end;

存儲過程學習-9 游標cursor

當查詢返回多條記錄時,需要循環,就要使用到cursor。

1 cursor定義
游標就像查詢數據返回的集合類型,比如List,把它當做一個引用類型,指向內存中查詢結果集。

2 cursor例子
create or replace procedure pro_with_cursor(v_name varchar2)
is
CURSOR test_cursor is select id, name, type from pca_project where name=v_name;
v_cursor test_cursor%ROWTYPE; -- 因為select出來是行記錄,可以使用%ROWTYPE, v_cursor表示一行記錄的對象
BEGIN
for v_cursor in test_cursor loop
exit when test_cursor%notfound;
dbms_output.putline('數據是:' || v_cursor.id ||''||v_cursor.name ||''||v_cursor.type);
end loop;
END;

注意到:游標的操作步驟:聲明游標,打開游標,提取數據,結束游標。但loop循環沒有顯示打開游標和關閉游標。

存儲過程學習-10 遍歷游標的方法for fetch while

create or replace procedure myprocedure is
CURSOR CUR_TEST IS --聲明顯式游標
SELECT ECODE,ENAME
FROM EMP;
CUR CUR_TEST%ROWTYPE; --定義游標變量,該變量的類型為基於游標C_EMP的記錄

BEGIN 
  --For 循環
  FOR CUR IN CUR_TEST LOOP
      --循環體
    DBMS_OUTPUT.PUT_LINE('員工編號:'||CUR.ECODE ||'員工姓名:'|| CUR.ENAME);
  END LOOP;

  --Fetch 循環
  OPEN CUR_TEST;--必須要明確的打開和關閉游標
  LOOP 
    FETCH CUR_TEST INTO CUR;
    EXIT WHEN CUR_TEST%NOTFOUND;
    --循環體
    DBMS_OUTPUT.PUT_LINE('員工編號:'||CUR.ECODE ||'員工姓名:'|| CUR.ENAME);
  END LOOP;
  CLOSE C_EMP;

  --While 循環
  OPEN CUR_TEST;--必須要明確的打開和關閉游標
    FETCH CUR_TEST INTO CUR;
    WHILE CUR_TEST%FOUND LOOP  
      --循環體
      DBMS_OUTPUT.PUT_LINE('員工編號:'||CUR.ECODE ||'員工姓名:'|| CUR.ENAME);

      FETCH CUR_TEST INTO CUR;
    END LOOP;
  CLOSE C_EMP;



END myprocedure; 

從代碼中可以很明顯的看出:

1 使用for循環不需要關注游標是否打開或關閉。
2 for循環會自動將數據fetch到記錄型變量。
3 for循環不需要關注何時要退出,也就是不需要寫退出滿足條件。遍歷完成就會退出。

存儲過程學習11-賦值、相等、分支

1 賦值
i := 0

2 相等
i=0 不相等<>

3 分支
if(條件1) then ... elsif(條件2)then ... else... end if

4 例子
create or replace procedure test_select5_procedure
(innum number,outnum out number)
AS
BEGIN
if (innum > 5) then --(判斷條件是否大於5 ,滿足條件則以then標識進入當前分支)
if(innum = 10) then -- (= 為相等)
outnum := 20; -- (:= 表示賦值)
else
outnum := innum + 1 ;
end if; --- (每個分支的結束都以 end if;來結束)
dbms_output.put_line('第一個分支:'||outnum);
elsif (innum > 0) then --- (elsif 的寫法注意,親測必須這么寫才行,寫成else if不行的)
outnum := innum - 1 ;
dbms_output.put_line('第二個分支:'||outnum);
else
outnum := -1 ;
dbms_output.put_line('第三個分支:'||outnum);
end if; --- (每個分支的結束都以 end if;來結束)
END;

存儲過程學習11-case

create or replace procedure test_case_procedure(idnum varchar)
as
v_project pca_project%rowtype;
begin
select * into v_project from pca_project where id=idnum;
case v_project.sex
when '女' then
dbms_output.put_line('女人');
when '男' then
dbms_output.put_line('男人');
else
dbms_output.put_line('人妖');
end case;
end;


免責聲明!

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



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