oracle 存儲過程的基本語法
目前成都創(chuàng)新互聯(lián)已為上1000+的企業(yè)提供了網(wǎng)站建設(shè)、域名、網(wǎng)頁空間、網(wǎng)站改版維護、企業(yè)網(wǎng)站設(shè)計、石峰網(wǎng)站維護等服務(wù),公司將堅持客戶導(dǎo)向、應(yīng)用為本的策略,正道將秉承"和諧、參與、激情"的文化,與客戶和合作伙伴齊心協(xié)力一起成長,共同發(fā)展。
1.基本結(jié)構(gòu)
CREATE OR REPLACE PROCEDURE 存儲過程名字
(
參數(shù)1 IN NUMBER,
參數(shù)2 IN NUMBER
) IS
變量1 INTEGER :=0;
變量2 DATE;
BEGIN
END 存儲過程名字
2.SELECT INTO STATEMENT
將select查詢的結(jié)果存入到變量中,可以同時將多個列存儲多個變量中,必須有一條
記錄,否則拋出異常(如果沒有記錄拋出NO_DATA_FOUND)
例子:
BEGIN
SELECT col1,col2 into 變量1,變量2 FROM typestruct where xxx;
EXCEPTION
WHEN NO_DATA_FOUND THEN
xxxx;
END;
...
3.IF 判斷
IF V_TEST=1 THEN
BEGIN
do something
END;
END IF;
4.while 循環(huán)
WHILE V_TEST=1 LOOP
BEGIN
XXXX
END;
END LOOP;
5.變量賦值
V_TEST := 123;
6.用for in 使用cursor
...
IS
CURSOR cur IS SELECT * FROM xxx;
BEGIN
FOR cur_result in cur LOOP
BEGIN
V_SUM :=cur_result.列名1+cur_result.列名2
END;
END LOOP;
END;
7.帶參數(shù)的cursor
CURSOR C_USER(C_ID NUMBER) IS SELECT NAME FROM USER WHERE TYPEID=C_ID;
OPEN C_USER(變量值);
LOOP
FETCH C_USER INTO V_NAME;
EXIT FETCH C_USER%NOTFOUND;
do something
END LOOP;
CLOSE C_USER;
8.用pl/sql developer debug
連接數(shù)據(jù)庫后建立一個Test WINDOW
在窗口輸入調(diào)用SP的代碼,F9開始debug,CTRL+N單步調(diào)試
Oracle存儲過程基本語法:
CREATE?OR?REPLACE?PROCEDURE?存儲過程名?
IS?
BEGIN?
NULL;?
END;
解釋:
行1:?
CREATE OR REPLACE PROCEDURE 是一個SQL語句通知Oracle數(shù)據(jù)庫去創(chuàng)建一個叫做skeleton存儲過程, 如果存在就覆蓋它;?
行2:?
IS關(guān)鍵詞表明后面將跟隨一個PL/SQL體。?
行3:?
BEGIN關(guān)鍵詞表明PL/SQL體的開始。?
行4:?
NULL PL/SQL語句表明什么事都不做,這句不能刪去,因為PL/SQL體中至少需要有一句;?
行5:?
END關(guān)鍵詞表明PL/SQL體的結(jié)束。
給你示例你參考下:
----------------------------建立存儲過程:
CREATE OR REPLACE PROCEDURE P_name--存儲過程名字
(
i_var in int, --輸入?yún)?shù)1
o_var OUT varchar2 --輸出參數(shù)1
)
IS
v_STR VARCHAR2(200); --定義存儲過程內(nèi)部的局部變量
BEGIN
--下面是存儲過程的主體實現(xiàn)部分
v_STR := i_var;
dbms_output.put_line(v_STR);
o_var := v_STR;
exception--錯誤異常處理部分
when others then
dbms_output.put_line(sqlerrm);--打印錯誤信息
END P_name;
-----------------------------------調(diào)用存儲過程示例:
declare
v_in int;
v_out varchar2(50);
begin
v_in :=100;
P_name (v_in,v_out); --調(diào)用存儲過程P_name
dbms_output.put_line('存儲過程輸入結(jié)果為:'||v_out);
exception--錯誤異常處理部分
when others then
dbms_output.put_line(sqlerrm);--打印錯誤信息
end;
Oracle存儲過程寫法實例
總結(jié)項目中寫的存儲過程例子:
Oracle存儲過程基本語法 存儲過程
1 CREATE OR REPLACE PROCEDURE 存儲過程名
2 IS/AS
3 BEGIN
4 NULL;
5 EXCEIPTION;
6 END;
1、創(chuàng)建存儲過程,后面可用is或者as:
create or replace procedure PRO_COMPLAIN_TEMPLATE as
2、定義變量,此處用到了%TYPE和%ROWTYPE,參考 /database/201211/168564.html ,另外定義了一個游標,TEM_INSTANCE TEMPLATE_CUR%ROWTYPE這個類型定義必須要在游標定義之后:
NEED_DO_FOR_ZL INTEGER;
CURRENT_MAX_ID MEMO_TEMPLET.TEMPLET_ID%TYPE;
CURSOR TEMPLATE_CUR IS SELECT TEMPLET_NAME, TEMPLET_CONTENT FROM SYS_COMPLAINT_TEMPLET;
TEM_INSTANCE TEMPLATE_CUR%ROWTYPE;
3、begin開始塊:
begin
4、該插入語句使用了DBLINK,還有使用DBMS_OUTPUT.put_line('打印信息')進行信息輸出:
insert into MEMO_TEMPLET (TEMPLET_ID, TEMPLET_CONTENT, TEMPLET_TYPE, TEMPLET_MEMO) (SELECT * FROM MEMO_TEMPLET@COMPANY);
SELECT COUNT(*) INTO NEED_DO_FOR_ZL FROM SYS_COMPLAINT_TEMPLET;
IF(NEED_DO_FOR_ZL 0) THEN
DBMS_OUTPUT.put_line('打印信息');
SELECT MAX(TEMPLET_ID)+1 INTO CURRENT_MAX_ID FROM MEMO_TEMPLET;
DBMS_OUTPUT.put_line('MEMO_TEMPLET最大ID' || CURRENT_MAX_ID);
FOR TEM_INSTANCE IN TEMPLATE_CUR LOOP
INSERT INTO MEMO_TEMPLET (TEMPLET_ID, TEMPLET_CONTENT,
TEMPLET_TYPE, TEMPLET_MEMO) VALUES (CURRENT_MAX_ID,
TEM_INSTANCE.TEMPLET_CONTENT, '7', NULL);
CURRENT_MAX_ID := CURRENT_MAX_ID + 1;
DBMS_OUTPUT.put_line(TEM_INSTANCE.TEMPLET_CONTENT);
END LOOP;
END IF;
COMMIT;
4、exception塊,使用WHEN OTHERS THEN,其中用raise可顯示錯誤信息:
exception
WHEN OTHERS THEN
DBMS_OUTPUT.put_line('sqlcode : ' ||sqlcode);
raise;
ROLLBACK;
IF TEMPLATE_CUR%ISOPEN THEN
CLOSE TEMPLATE_CUR;
END IF;
DBMS_OUTPUT.put_line('打印信息');
end;
注:關(guān)于游標的使用,如果像本例中使用for循環(huán)去遍歷游標的話則不需要顯式的去用open/close
cursor打開和關(guān)閉游標,此處會自己處理,如果使用fetch
into的話就需要顯式開關(guān)游標,另外任意執(zhí)行一個update操作,用隱式游標sql的屬性%found,%notfound,%rowcount,%isopen觀察update語句的執(zhí)行情況,也可以使用來判斷游標狀態(tài),如IF
TEMPLATE_CUR%ISOPEN THEN。
---創(chuàng)建
create or replace procedure GenTestUserData(nRecordCount in number Default 50000) is
nCurrentCount number; -- 當前表中記錄
nMaxLogID number;
nInsertCount number;
begin
select Count(LogID), Nvl(Max(LogID), 0)
into nCurrentCount, nMaxLogID
from MyUser;
nInsertCount:= nRecordCount - nCurrentCount;
if nInsertCount = 0 then
Return;
end if;
-- 插入數(shù)據(jù)
insert into MyUser(FirstName, LastName, LogID, Mail, Location)
select FirstName, LastName, LogID, 'MyUser@' || To_Char(LogID) || '.Com', '.' || To_Char(LogID) || '.Com'
from (select GetRandomHZ FirstName, GetRandomHZ LastName, nMaxLogID + Rownum LogID
from All_Tab_Columns
where Rownum = nInsertCount) TestData;
end;
/
--刪掉
drop procedure GenTestUserData;
存儲過程(procedure):是一個命名了的語句塊,可以有0個或多個參數(shù)
語法:
create or replace procedure HelloWorld
as
begin
dbms_output.put_line('HelloWorld');
end;
調(diào)用存儲過程
* 命令調(diào)用 exec helloworld
* 語句塊調(diào)用
begin
helloworld;
end;
/
DELETE:
create or replace procedure del_emp01
is
begin
delete from emp01 where empno=7369;
end;
exec del_emp01;
create or replace procedure del_emp01(v_empno in emp01.empno%type)
is
begin
delete from emp01 wherer empno=v_empno;
end;
exec del_emp01(7521);
INSERT
create or replace procedure ins_emp01
(v_empno emp01.empno%type,v_ename emp01.ename%type)
as
begin
insert into emp01(empno,ename) values(v_empno,v_ename);
end;
exec ins_emp01(1000,'李四');
UPDATE
create or replace procedure upd_emp01
(v_empno emp01.empno%type,v_ename emp01.ename%type)
as
begin
update emp01 set ename=v_ename where empno=v_empno;
end;
exec upd_emp01(1000,'張三');
SELECT
create or replace procedure sel_emp01
(v_empno emp01.empno%type,v_emp01_data out emp01%rowtype)
as
begin
select * into v_emp01_data from emp where empno=v_empno;
end;
帶有輸出參數(shù)的存儲過程不能使用命令直接調(diào)用
只能由語句塊或程序調(diào)用(JAVA) ****************************************************************
declare
v_emp_data emp01%rowtype;
begin
sel_emp01(7499,v_emp_data);
dbms_output.put_line(v_emp_data.ename||' '||v_emp_data.sal);
end;
調(diào)用:
declare
v_emp_data emp01%rowtype;
begin
sel_emp01(7499,v_emp_data);
dbms_output.put_line(v_emp_data.ename||' '||v_emp_data.sal);
end;
使用scott用戶登錄
統(tǒng)計某個部門的員工的工資總和,員工的人數(shù),平均工資,創(chuàng)建存儲過程
create or replace procedure deptcount
(v_deptno emp.deptno%type,v_sal_sum out number,v_recordes out number,v_avg_sal out number,errorMsg out varchar2)
is
begin
select sum(sal) into v_sal_sum from emp group by deptno having deptno=v_deptno;
select count(*) into v_recordes from emp group by deptno having deptno=v_deptno;
select avg(sal) into v_avg_sal from emp group by deptno having deptno=v_deptno;
exception
when no_data_found then
errorMsg:='沒有該部門';
end;
調(diào)用:
declare
v_sal_sum number;
v_recordes number;
v_avg_sal number(8,2);
v_errormsg varchar2(20);
begin
deptcount(90,v_sal_sum,v_recordes,v_avg_sal,v_errormsg);
dbms_output.put_line(v_sal_sum||' '||v_recordes||' '||v_avg_sal);
dbms_output.put_line(v_errormsg);
end;
//輸出參數(shù)
create or replace procedure my_pro(v_num in number,v_result out number)
is
v_temp number;
begin
v_temp:=0;
for i in 1..v_num
loop
v_temp:=v_temp+i;
end loop;
v_result:=v_temp;
end;
declare
v_recieve number;
begin
my_pro(100,v_recieve);
dbms_output.put_line(v_recieve);
end;
//既是輸入?yún)?shù)又是輸出參數(shù)
create or replace procedure my_pro1(v_i in out number)
is
v_j number;
begin
v_j:=30;
v_i:=v_i*v_j;
end;
declare
v_t number;
begin
v_t:=20;
my_pro1(v_t);
dbms_output.put_line(v_t);
end;