一、存儲過程
存儲過程是一組為了完成特定功能的SQL 語句集,經編譯後存儲在數據庫中,用戶通過指定存儲過程的名字並給出參數(如果該存儲過程帶有參數)來執行它。oracle可以把PL/SQL程序儲存在數據庫中,並可以在任何地方來運行它。存儲過程被稱為PL/SQL子程序,是被命名的PL/SQL快,存儲在數據庫,通過輸入、輸出參數與調用者交換信息。oracle存儲過程不返回數據。
語法:
create or replace procudure 存儲過名稱(
參數名稱 輸入輸出類型 參數類型,
參數名稱 輸入輸出類型 參數類型
)
is
begin
處理語句;
exceeption;
異常處理語句;
end 存儲過名稱;
輸出輸出類型有如下三種:
輸出輸出參數類型一般不聲明長度,因為對於IN參數,其寬度是由外部決定。 對於OUT 和IN OUT 參數,其寬度是由存儲過程內部決定。對於沒有說明輸入輸出類型的參數,默認為IN類型。
二、示例
以下代碼person表結構如下:
DROP TABLE person ; CREATE TABLE person ( id NUMBER(11) NOT NULL , username VARCHAR2(255 ) NULL , age NUMBER(11) NULL , password VARCHAR2(255) NULL , PRIMARY KEY (id) ) INSERT INTO person VALUES ('1', '張三', '100', 'zhang123'); INSERT INTO person VALUES ('2', '李四', '20', 'lisi123'); INSERT INTO person VALUES ('3', '王五', '20', 'wang123'); INSERT INTO person VALUES ('4', '趙六', '20', 'zhao123');
1、查詢一個(in、out)
create or replace procedure pro_person_getbyid( p_id in number, p_username out varchar2, p_age out number, p_password out varchar2 ) is begin select username, age, password into p_username, p_age, p_password from person where id = p_id; end pro_person_getbyid; -- 調用代碼 -------------- declare v_id number; v_username varchar2(255); v_age number; v_password varchar2(255); begin v_id := 1; pro_person_getbyid(v_id, v_username, v_age, v_password); dbms_output.put_line('username:'||v_username||' age:'||v_age||' password:'||v_password); end;
2、查詢一個(in、out)使用rowtype
create or replace procedure pro_person_getrow( p_id in number, p_row out person%rowtype, -- rowtype類型變量 p_count out number -- 標記是否找到記錄 ) is begin select * into p_row from person where id = p_id; p_count := SQL%ROWCOUNT; exception when no_data_found then p_count := 0; end pro_person_getrow; -- 調用-------------- declare v_id number := 28; v_row person%rowtype; v_count number; begin pro_person_getrow(v_id, v_row, v_count); dbms_output.put_line(v_count); dbms_output.put_line('id:'||v_row.id||' username:'||v_row.username||' age:'||v_row.age||' password:'||v_row.password); end;
3、添加記錄(in、out)
create or replace procedure pro_person_insert( p_id number, p_username varchar2, p_age number, p_password varchar2, p_count out number -- 是否添加成功 ) is begin insert into person (id, username, age, password) values(p_id, p_username, p_age, p_password); p_count := SQL%ROWCOUNT; -- SQL%ROWCOUNT為 隱式游標的屬性 commit; exception when others then p_count := 0; -- 失敗 end pro_person_insert; -- 調用procedure declare v_id number := 28; v_username varchar2(255) := 'xiaoli'; v_age number := 19; v_password varchar2(255) := 'xiao123'; v_count number; begin pro_person_insert(p_id => v_id, p_username => v_username, p_age => v_age, p_password => v_password, p_count => v_count); -- pro_person_insert(v_id , v_username, v_age, v_password, v_count); dbms_output.put_line('影響行數'||v_count); end;
4、更新(in、out)
create or replace procedure pro_person_update( p_id number, p_age number, p_password varchar2, p_count out number ) is begin update person set age = p_age, password = p_password where id = p_id; p_count := SQL%ROWCOUNT; commit; exception when no_data_found then p_count := 0; when others then p_count := -1; end pro_person_update; -- 調用--------------------- declare v_id number := 28; v_age number := 19; v_password varchar2(255) := 'password'; v_count number; begin pro_person_update(v_id, v_age, v_password, v_count); dbms_output.put_line('影響行數'||v_count); end;
5、刪除(in、out)
create or replace procedure pro_person_delete( p_id number, p_count out number ) is begin delete from person where id = p_id; p_count := SQL%ROWCOUNT; commit; exception when no_data_found then p_count := 0; when others then p_count := -1; end pro_person_delete; -- 調用---------------- declare v_id number := 28; v_count number; begin pro_person_delete(v_id, v_count); dbms_output.put_line('影響行數'||v_count); end;
6、查詢所有(in、out)使用sys_refcursor
create or replace procedure pro_person_findall2( p_cursor out sys_refcursor -- 輸出參數為包類型 ) is begin open p_cursor for select * from person; exception when others then DBMS_OUTPUT.PUT_LINE('獲取信息發生錯誤'); end pro_person_findall2; ----調用--------------------------------------------------- declare c_cursor sys_refcursor; r_person person%rowtype; begin pro_person_findall2(c_cursor); --2、打開游標 -- open c_cursor; --此處不需要顯示地打開游標,因為調用存儲過程的時候返回的游標已經打開了 --3、提取數據 loop fetch c_cursor into r_person; exit when c_cursor%notfound; -- 下面沒有數據的時候,退出 dbms_output.put_line('id:'||r_person.id); dbms_output.put_line('username:'||r_person.username); dbms_output.put_line('age:'||r_person.age); end loop; end;
7、查詢所有(in、out)使用自定義類型查詢
-- 創建一個包類型 create or replace package pkg_const as type r_cursor is ref cursor; end pkg_const; -- 創建存儲過程, create or replace procedure pro_person_findall( p_cursor out pkg_const.r_cursor -- 輸出參數為包類型 ) is begin open p_cursor for select * from person; exception when others then DBMS_OUTPUT.PUT_LINE('獲取信息發生錯誤'); end pro_person_findall; ----調用------------------------------------ declare c_cursor pkg_const.r_cursor; r_person person%rowtype; begin pro_person_findall(c_cursor); --2、打開游標 -- open c_cursor; --3、提取數據 loop fetch c_cursor into r_person; exit when c_cursor%notfound; -- 下面沒有數據的時候,退出 dbms_output.put_line('id:'||r_person.id); dbms_output.put_line('username:'||r_person.username); dbms_output.put_line('age:'||r_person.age); end loop; end;
三、存儲過程其他語句
查看存儲過程
DESCRIBE 存儲過程名;
刪除存儲過程
DROP PROCEDURE 存儲過程名;
右鍵點表 view 再點右下角 view sql 就能看了或者edit都可以
看你存儲過程裡是否有參數了
正常的話,在左邊列表找到procedure裡找到你寫的那存儲過程名,看上邊有紅叉沒,沒紅叉就是編譯成功,有紅叉就是還有問題,需要改
然後右鍵點這個存儲過程,(中文版選擇測試按鈕,英文版選擇test按鈕),然後下邊有輸入參數的地方,輸入,點上邊的齒輪即可
還有種方法,就是開一個sql窗口,寫以下代碼
begin
存儲過程名;
end;
然後點齒輪運行,注意兩個分號不可少