oracle存儲過程怎麼寫
⑴ oracle存儲過程怎麼寫循環
寫循環的操作方法和步驟如下:
1、第一步,編寫存儲過程的整體結構,然後定義變數,見下圖。
⑵ 寫一個oracle存儲過程
大致寫了下,需要藉助一個臨時表,所有的更新在臨時中進行,最後合並到正式表中,代碼如下,可以根據實際的業務邏輯改一下,供參考
sql">--首先創建臨時表
createtableODS_TRANS_TMPas
select*fromODS_TRANSwhere1=2;
--下面為更新的存儲過程
createorreplaceprocerep_update_opp_acctis
begin
--向臨時表寫入數據
insertintoODS_TRANS_TMP--將需要更新的記錄,插入到臨時表
select*
fromODS_TRANSt
whereDR_CR_FLAG=1
andOPP_ACCT_NUMisnull
andTRANS_IDin(select1
from(selectTRANS_ID,TRANS_DT
fromODS_TRANS
whereOPP_ACCT_NUMisnull
groupbyTRANS_ID,TRANS_DT
havingcount(1)=2)a--首先找到對方賬號為空的記錄,按TRANS_ID,TRANS_DT分組,必須同時為2條
wheret.TRANS_ID=a.TRANS_ID
andt.TRANS_DT=a.TRANS_DT);
--臨時表中,更新對方賬號欄位
mergeintoODS_TRANS_TMPa
using(selectTRANS_ID,TRANS_DT,ACCT_NUM
fromODS_TRANS_TMP
whereDR_CR_FLAG=1)b
on(a.DR_CR_FLAG=0anda.TRANS_ID=b.TRANS_IDanda.TRANS_DT=b.TRANS_DT)
whenmatchedthen
updateseta.OPP_ACCT_NUM=b.ACCT_NUM;
mergeintoODS_TRANS_TMPa
using(selectTRANS_ID,TRANS_DT,ACCT_NUM
fromODS_TRANS_TMP
whereDR_CR_FLAG=0)b
on(a.DR_CR_FLAG=1anda.TRANS_ID=b.TRANS_IDanda.TRANS_DT=b.TRANS_DT)
whenmatchedthen
updateseta.OPP_ACCT_NUM=b.ACCT_NUM;
--臨時表合並到正式表
mergeintoODS_TRANSa
usingODS_TRANS_TMPb
on(a.TRANS_ID=b.TRANS_IDanda.TRANS_DT=b.TRANS_DTanda.DR_CR_FLAG=b.DR_CR_FLAG)
whenmatchedthen
updateseta.OPP_ACCT_NUM=b.OPP_ACCT_NUM;
--刪除臨時表中的數據
deletefromODS_TRANS_TMP;
commit;
exception
whenothersthen
rollback;
end;
⑶ Oracle 的存儲過程怎麼寫。
oracle 存儲過程的基本語法
1.基本結構
CREATE OR REPLACE PROCEDURE 存儲過程名字
(
參數1 IN NUMBER,
參數2 IN NUMBER
) IS
變數1 INTEGER :=0;
變數2 DATE;
BEGIN
END 存儲過程名字
2.SELECT INTO STATEMENT
將select查詢的結果存入到變數中,可以同時將多個列存儲多個變數中,必須有一條
記錄,否則拋出異常(如果沒有記錄拋出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 循環
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.帶參數的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
連接資料庫後建立一個Test WINDOW
在窗口輸入調用SP的代碼,F9開始debug,CTRL+N單步調試
⑷ oracle存儲過程基本語法
一:存儲過程
創建存儲過程,需要有CREATE PROCEDURE或CREATE ANY PROCEDURE的系統許可權
刪除存儲過程,是過程的創建者或者擁有DROP ANY PROCEDURE系統許可權
修改存儲過程,則只能是過程的創建者或者擁有ALTER ANY PROCEDURE系統許可權的人
執行(或調用)存儲過程,是過程的創建者或是擁有EXECUTE ANY PROCEDURE系統許可權的人或是被擁有者授予EXECUTE許可權的人
1:語法
1)創建
CREATE[ORREPLACE]PROCEDURE存儲過程名[(參數[IN|OUT|INOUT] 數據類型...)]
{AS|IS}
[說明部分]
BEGIN
可執行部分
[EXCEPTION
錯誤處理部分]
END[過程名];
說明:
OR REPLACE 表示如果存在就覆蓋存儲過程
參數有三種形式:IN、OUT和IN OUT。則默認為IN。
關鍵字AS也可以寫成IS,後跟過程的說明部分,可以在此定義過程的局部變數。
2)刪除存儲過程:
DROP PROCEDURE 存儲過程名;
3)修改存儲過程:
ALTER PROCEDURE 存儲過程名 COMPILE;
4)執行存儲過程
EXECUTE 模式名.存儲過程名[(參數...)];
或
BEGIN
模式名.存儲過程名[(參數...)];
END;
另外:參數可以是變數、常量或表達式
要其它用戶執行存儲過程須要給其它用戶授權
GRANT EXECUTE ON 存儲過程名 TO 用戶名
2:參數說明
IN 定義一個輸入參數變數,用於傳遞參數給存儲過程
OUT 定義一個輸出參數變數,用於從存儲過程獲取數據
IN OUT 定義一個輸入、輸出參數變數,兼有以上兩者的功能
1)參數名 IN 數據類型 DEFAULT 值;
定義一個輸入參數變數,用於傳遞參數給存儲過程。
可以是常量、有值變數或表達式
DEFAULT 關鍵字為可選項,用來設定參數的默認值。如果在調用存儲過程時不指明參數,則參數變數取默認值
在存儲過程中,輸入變數接收主程序傳遞的值,但不能對其進行賦值。
2)參數名 OUT 數據類型;
定義一個輸出參數變數,用於從存儲過程獲取數據,即變數從存儲過程中返回值給主程序。
在調用存儲過程時,主程序的實際參數只能是一個變數,而不能是常量或表達式。
在存儲過程中,參數變數只能被賦值而不能將其用於賦值,而且必須給輸出變數至少賦值一次。
3)參數名 IN OUT 數據類型 DEFAULT 值;
定義一個輸入、輸出參數變數,兼有以上兩者的功能。
在調用存儲過程時,主程序的實際參數只能是一個變數,而不能是常量或表達式。
DEFAULT 關鍵字為可選項,用來設定參數的默認值。
在存儲過程中,變數接收主程序傳遞的值,同時可以參加賦值運算,也可以對其進行賦值。在存儲過程中必須給變數至少賦值一次。
補充:如果省略IN、OUT或IN OUT,則默認模式是IN。
調用它時參數個數與位置可以不一致,用以下形式調用:
EXECUTE CHANGE_SALARY(P_RAISE=>80,P_EMPNO=>7788); //=>運算符左側是參數名,右側是參數表達式
二:函數
創建函數,需要有CREATE PROCEDURE或CREATE ANY PROCEDURE的系統許可權
刪除函數,需要是函數的創建者或者是擁有DROP ANY PROCEDURE系統許可權的人
修改函數,需要是函數的創建者或者擁有ALTER ANY PROCEDURE系統許可權的人
執行函數,需要是函數的創建者或擁有EXECUTE ANY PROCEDURE系統許可權的人
1:語法
1)創建:
CREATE[ORREPLACE]FUNCTION函數名[(參數[IN] 數據類型...)]
RETURN數據類型
{AS|IS}
[說明部分]
BEGIN
可執行部分
RETURN(表達式)
[EXCEPTION
錯誤處理部分]
END[函數名];
說明:
參數是可選的,但只能是IN類型(IN關鍵字可以省略)。
在定義部分的RETURN 數據類型,用來表示函數的數據類型,也就是返回值的類型,不可省略。
在可執行部分的RETURN(表達式),用來生成函數的返回值,其表達式的類型應該和定義部分說明的函數返回值的數據類型一致。在函數的執行部分可以有多個RETURN語句,但只有一個RETURN語句會被執行,一旦執行了RETURN語句,則函數結束並返回調用環境。
2)刪除
DROP FUNCTION 函數名;
3)修改
ALTER PROCEDURE 函數名 COMPILE;
4)執行
變數名:=函數名(...)
三:對存儲過程 和 函數的查看(可以通過對數據字典【USER_SOURCE】的訪問來查詢存儲過程或函數的有關信息)
1:查詢某個存儲過程序內容
select TEXT from user_source WHERE NAME='存儲過程名';
2:查看數據字殿
DESCRIBE USER_SOURCE ; //命令行中
3:查看存儲過程的參數
DESCRIBE say_hello; //後面是過程名
4:查看發生編輯錯誤
SHOW ERRORS ;
5:查詢一個存儲過程或函數是否是有效狀態(即編譯成功)
SELECT STATUS FROM USER_OBJECTS WHERE OBJECT_NAME='過程名';//注意大小寫
VALID表示該存儲過程有效(即通過編譯),INVALID表示存儲過程無效或需要重新編譯。它的狀態會改變,這與它依賴外部表(表刪除修改等操作)有關系
6:查看存儲過程與表的依賴關系
SELECT REFERENCED_NAME,REFERENCED_TYPE FROM USER_DEPENDENCIES WHERE NAME='SAY_HELLO';
說明
NAME為實體名,TYPE為實體類型,REFERENCED_OWNER為涉及到的實體擁有者賬戶,REFERENCED_NAME為涉及到的實體名,REFERENCED_TYPE 為涉及到的實體類型。
問題:
如果一個用戶A被授予執行屬於用戶B的一個存儲過程的許可權,在用戶B的存儲過程中,訪問到用戶C的表,用戶B被授予訪問用戶C的表的許可權,但用戶A沒有被授予訪問用戶C表的許可權,那麼用戶A調用用戶B的存儲過程是失敗的還是成功的呢?答案是成功的。
⑸ oracle怎麼寫存儲過程
給你示例你參考下:
----------------------------建立存儲過程:
CREATE OR REPLACE PROCEDURE P_name--存儲過程名字
(
i_var in int, --輸入參數1
o_var OUT varchar2 --輸出參數1
)
IS
v_STR VARCHAR2(200); --定義存儲過程內部的局部變數
BEGIN
--下面是存儲過程的主體實現部分
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;
-----------------------------------調用存儲過程示例:
declare
v_in int;
v_out varchar2(50);
begin
v_in :=100;
P_name (v_in,v_out); --調用存儲過程P_name
dbms_output.put_line('存儲過程輸入結果為:'||v_out);
exception--錯誤異常處理部分
when others then
dbms_output.put_line(sqlerrm);--列印錯誤信息
end;
⑹ oracle中的存儲過程怎麼寫
Oracle存儲過程寫法實例
總結項目中寫的存儲過程例子:
Oracle存儲過程基本語法 存儲過程
1 CREATE OR REPLACE PROCEDURE 存儲過程名
2 IS/AS
3 BEGIN
4 NULL;
5 EXCEIPTION;
6 END;
1、創建存儲過程,後面可用is或者as:
create or replace procere 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;
www.2cto.com
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;
註:關於游標的使用,如果像本例中使用for循環去遍歷游標的話則不需要顯式的去用open/close
cursor打開和關閉游標,此處會自己處理,如果使用fetch
into的話就需要顯式開關游標,另外任意執行一個update操作,用隱式游標sql的屬性%found,%notfound,%rowcount,%isopen觀察update語句的執行情況,也可以使用來判斷游標狀態,如IF
TEMPLATE_CUR%ISOPEN THEN。
⑺ Oracle資料庫的存儲過程怎麼寫
1 CREATE OR REPLACE PROCEDURE 存儲過程名
2 IS
3 BEGIN
4 NULL;
5 END;
行1:
CREATE OR REPLACE PROCEDURE 是一個SQL語句通知Oracle資料庫去創建一個叫做skeleton存儲過程, 如果存在就覆蓋它;
行2:
IS關鍵詞表明後面將跟隨一個PL/SQL體。
行3:
BEGIN關鍵詞表明PL/SQL體的開始。
行4:
NULL PL/SQL語句表明什麼事都不做,這句不能刪去,因為PL/SQL體中至少需要有一句;
行5:
END關鍵詞表明PL/SQL體的結束.
存儲過程創建語法:
create or replace procere 存儲過程名(param1 in type,param2 out type)
as
變數1 類型(值范圍); --vs_msgVARCHAR2(4000);
變數2 類型(值范圍);
Begin
Select count(*) into 變數1 from 表A where列名=param1;
If (判斷條件) then
Select 列名 into 變數2 from 表A where列名=param1;
Dbms_output。Put_line(『列印信息』);
Elsif (判斷條件) then
Dbms_output。Put_line(『列印信息』);
Else
Raise 異常名(NO_DATA_FOUND);
End if;
Exception
When others then
Rollback;
End;
⑻ oracle存儲過程並且怎麼寫
存儲過程(procere):是一個命名了的語句塊,可以有0個或多個參數
語法:
create or replace procere HelloWorld
as
begin
dbms_output.put_line('HelloWorld');
end;
調用存儲過程
* 命令調用 exec helloworld
* 語句塊調用
begin
helloworld;
end;
/
DELETE:
create or replace procere del_emp01
is
begin
delete from emp01 where empno=7369;
end;
exec del_emp01;
create or replace procere 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 procere 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 procere 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 procere 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;
帶有輸出參數的存儲過程不能使用命令直接調用
只能由語句塊或程序調用(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;
調用:
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用戶登錄
統計某個部門的員工的工資總和,員工的人數,平均工資,創建存儲過程
create or replace procere 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;
調用:
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;
//輸出參數
create or replace procere 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;
//既是輸入參數又是輸出參數
create or replace procere 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;
⑼ oracle存儲過程循環怎麼寫
Oracle中有三種循環(For、While、Loop):
1、loop循環:
createorreplaceprocerepro_test_loopis
inumber;
begin
i:=0;
loop
i:=i+1;
dbms_output.put_line(i);
ifi>5then
exit;
endif;
endloop;
endpro_test_loop;
2、while循環:
createorreplaceprocerepro_test_loopis
inumber;
begin
i:=0;
whilei<5loop
i:=i+1;
dbms_output.put_line(i);
endloop;
endpro_test_loop;
3、for循環1:
createorreplaceprocerepro_test_foris
inumber;
begin
i:=0;
foriin1..5loop
dbms_output.put_line(i);
endloop;
endpro_test_for;
4、for循環2:
createorreplaceprocerepro_test_cursoris
userRowt_user%rowtype;
cursoruserRowsis
select*fromt_user;
begin
foruserRowinuserRowsloop
dbms_output.put_line(userRow.Id||','||userRow.Name||','||userRows%rowcount);
endloop;
endpro_test_cursor;
⑽ Oracle存儲過程游標for循環怎麼寫
一、不帶參數的游標for循環
1
首先編寫存儲過程的整體結構,如下:
create or replace procere test_proc is
v_date date; --變數定義胡睜磨
begin
select sysdate into v_date from al;
end test_proc;
2
定義游標:
create or replace procere test_proc is
v_date date; --定義變數
cursor cur is select * from ldcode; --定義游標
begin
select sysdate into v_date from al;
end test_proc;
3
編寫for循環:
create or replace procere test_proc is
v_date date; --定義變數
cursor cur is select * from ldcode where rownum<10; --定義游標
begin
select sysdate into v_date from al;
--游標for循環開始
for temp in cur loop --temp為臨時變數名,自己任意起
Dbms_Output.put_line(temp.Code); --輸出某個欄位,使用"變數名.列名"即可早擾。
end loop;
--游標for循環結束
end test_proc;
4
測試運行,點擊【DBMS Output】標簽頁查看結果如下圖:
END
二、帶參數的游標for循環
1
定義帶參數的游標:
cursor cur(v_codetype ldcode.Codetype%TYPE) is
select * from ldcode where codetype = v_codetype; --定義游標
定義游標格式:
cursor 游標名稱(變褲斗量定義) is 查詢語句;
注意:
where條件中的變數名v_codetype要與游標定義cur(v_codetype ldcode.Codetype%TYPE)中的一致。
2
編寫for循環部分:
--游標for循環開始
for temp in cur('llmedfeetype') loop
--temp為臨時變數名,自己任意起
--cur('llmedfeetype')為"游標名稱(傳入的變數)"
Dbms_Output.put_line(temp.Code); --輸出某個欄位,使用"變數名.列名"即可。
end loop;
--游標for循環結束
3
測試運行,點擊【DBMS Output