




版權(quán)說(shuō)明:本文檔由用戶(hù)提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
PAGEOracle存儲(chǔ)過(guò)程學(xué)習(xí)目錄Oracle存儲(chǔ)過(guò)程學(xué)習(xí) 1Oracle存儲(chǔ)過(guò)程基礎(chǔ)知識(shí) 1Oracle存儲(chǔ)過(guò)程的基本語(yǔ)法 2關(guān)于Oracle存儲(chǔ)過(guò)程的若干問(wèn)題備忘 41. 在Oracle中,數(shù)據(jù)表別名不能加as。 42. 在存儲(chǔ)過(guò)程中,select某一字段時(shí),后面必須緊跟into,如果select整個(gè)記錄,利用游標(biāo)的話(huà)就另當(dāng)別論了。 43. 在利用o...語(yǔ)法時(shí),必須先確保數(shù)據(jù)庫(kù)中有該條記錄,否則會(huì)報(bào)出"nodatafound"異常。 44. 在存儲(chǔ)過(guò)程中,別名不能和字段名稱(chēng)相同,否則雖然編譯可以通過(guò),但在運(yùn)行階段會(huì)報(bào)錯(cuò) 45. 在存儲(chǔ)過(guò)程中,關(guān)于出現(xiàn)null的問(wèn)題 56. Hibernate調(diào)用Oracle存儲(chǔ)過(guò)程 5用Java調(diào)用Oracle存儲(chǔ)過(guò)程總結(jié) 5一、 無(wú)返回值的存儲(chǔ)過(guò)程 6二、 有返回值的存儲(chǔ)過(guò)程(非列表) 7三、 返回列表 9在存儲(chǔ)過(guò)程中做簡(jiǎn)單動(dòng)態(tài)查詢(xún) 10一、 本地動(dòng)態(tài)SQL 11二、 使用DBMS_SQL包 12Oracle存儲(chǔ)過(guò)程調(diào)用Java方法 13Oracle高效分頁(yè)存儲(chǔ)過(guò)程實(shí)例 14Oracle存儲(chǔ)過(guò)程基礎(chǔ)知識(shí)商業(yè)規(guī)則和業(yè)務(wù)邏輯可以通過(guò)程序存儲(chǔ)在Oracle中,這個(gè)程序就是存儲(chǔ)過(guò)程。存儲(chǔ)過(guò)程是SQL,PL/SQL,Java語(yǔ)句的組合,它使你能將執(zhí)行商業(yè)規(guī)則的代碼從你的應(yīng)用程序中移動(dòng)到數(shù)據(jù)庫(kù)。這樣的結(jié)果就是,代碼存儲(chǔ)一次但是能夠被多個(gè)程序使用。要?jiǎng)?chuàng)建一個(gè)過(guò)程對(duì)象(proceduralobject),必須有CREATEPROCEDURE系統(tǒng)權(quán)限。如果這個(gè)過(guò)程對(duì)象需要被其他的用戶(hù)schema使用,那么你必須有CREATEANYPROCEDURE權(quán)限。執(zhí)行procedure的時(shí)候,可能需要excute權(quán)限?;蛘逧XCUTEANYPROCEDURE權(quán)限。如果單獨(dú)賦予權(quán)限,如下例所示:
grant
executeonMY_PROCEDURE
toJelly調(diào)用一個(gè)存儲(chǔ)過(guò)程的例子:executeMY_PROCEDURE('ONEPARAMETER');存儲(chǔ)過(guò)程(PROCEDURE)和函數(shù)(FUNCTION)的區(qū)別。function有返回值,并且可以直接在Query中引用function和或者使用function的返回值。本質(zhì)上沒(méi)有區(qū)別,都是PL/SQL程序,都可以有返回值。最根本的區(qū)別是:存儲(chǔ)過(guò)程是命令,
而函數(shù)是表達(dá)式的一部分。比如:selectmax(NAME)FROM但是不能execmax(NAME)如果此時(shí)max是函數(shù)。PACKAGE是function,procedure,variables和sql語(yǔ)句的組合。package允許多個(gè)procedure使用同一個(gè)變量和游標(biāo)。創(chuàng)建procedure的語(yǔ)法:CREATE[ORREPLACE]PROCEDURE[schema.]procedure[(argument[IN|OUT|INOUT][NOCOPY]datatype[,argument[IN|OUT|INOUT][NOCOPY]datatype]...)][authid{current_user|definer}]{is|as}{pl/sql_subprogram_body|language{javaname'String'|c[name,name]librarylib_name}]Sql代碼:CREATEPROCEDUREsam.credit(acc_noINNUMBER,amountINNUMBER)ASBEGINUPDATEaccountsSETbalance=balance+amountWHEREaccount_id=acc_no;END;可以使用createorreplaceprocedure語(yǔ)句,這個(gè)語(yǔ)句的用處在于,你之前賦予的excute權(quán)限都將被保留。IN,OUT,INOUT用來(lái)修飾參數(shù)。IN表示這個(gè)變量必須被調(diào)用者賦值然后傳入到PROCEDURE進(jìn)行處理。OUT表示PRCEDURE通過(guò)這個(gè)變量將值傳回給調(diào)用者。INOUT則是這兩種的組合。authid代表兩種權(quán)限:定義者權(quán)限(difinerright默認(rèn)),執(zhí)行者權(quán)限(invokerright)。定義者權(quán)限說(shuō)明這個(gè)procedure中涉及的表,視圖等對(duì)象所需要的權(quán)限只要定義者擁有權(quán)限的話(huà)就可以訪問(wèn)。執(zhí)行者權(quán)限則需要調(diào)用這個(gè)procedure的用戶(hù)擁有相關(guān)表和對(duì)象的權(quán)限。Oracle存儲(chǔ)過(guò)程的基本語(yǔ)法基本結(jié)構(gòu)CREATEORREPLACEPROCEDURE存儲(chǔ)過(guò)程名字
(
參數(shù)1INNUMBER,
參數(shù)2INNUMBER
)AS
變量1INTEGER:=0;
變量2DATE;
BEGINEND存儲(chǔ)過(guò)程名字SELECTINTOSTATEMENT將select查詢(xún)的結(jié)果存入到變量中,可以同時(shí)將多個(gè)列存儲(chǔ)多個(gè)變量中,必須有一條
記錄,否則拋出異常(如果沒(méi)有記錄拋出NO_DATA_FOUND)例子:BEGIN
SELECTcol1,col2into變量1,變量2FROMtypestructwherexxx;
EXCEPTION
WHENNO_DATA_FOUNDTHEN
xxxx;
END;
...IF判斷IFV_TEST=1THEN
BEGIN
dosomething
END;
ENDIF;while循環(huán)WHILEV_TEST=1LOOP
BEGIN
XXXX
END;
ENDLOOP;變量賦值V_TEST:=123;用forin使用cursor...
IS
CURSORcurISSELECT*FROMxxx;
BEGIN
FORcur_resultincurLOOP
BEGIN
V_SUM:=cur_result.列名1+cur_result.列名2
END;
ENDLOOP;
END;帶參數(shù)的cursorCURSORC_USER(C_IDNUMBER)ISSELECTNAMEFROMUSERWHERETYPEID=C_ID;
OPENC_USER(變量值);
LOOP
FETCHC_USERINTOV_NAME;
EXITFETCHC_USER%NOTFOUND;
dosomething
ENDLOOP;
CLOSEC_USER;用pl/sqldeveloperdebug
連接數(shù)據(jù)庫(kù)后建立一個(gè)TestWINDOW
在窗口輸入調(diào)用SP的代碼,F9開(kāi)始debug,CTRL+N單步調(diào)試Pl/Sql中執(zhí)行存儲(chǔ)過(guò)程在sql*plus中:
declare
--必要的變量聲明,視你的過(guò)程而定
begin
execute
yourprocudure(parameter1,parameter2,...);
end
/
在SQL/PLUS中調(diào)用存儲(chǔ)過(guò)程,顯示結(jié)果:SQL>setserveoutputon--打開(kāi)輸出SQL>varinfo1number;--輸出1SQL>varinfo2number;--輸出2SQL>declarevar1varchar2(20);--輸入1var2varchar2(20);--輸入2var3varchar2(20);--輸入2BEGINpro(var1,var2,var3,:info1,:info2);END;/SQL>printinfo1;SQL>printinfo2; 注:在EXECUTEIMMEDIATESTR語(yǔ)句是SQLPLUS中動(dòng)態(tài)執(zhí)行語(yǔ)句,它在執(zhí)行中會(huì)自動(dòng)提交,類(lèi)似于DP中FORMS_DDL語(yǔ)句,在此語(yǔ)句中str是不能換行的,只能通過(guò)連接字符"||",或著在在換行時(shí)加上"-"連接字符。關(guān)于Oracle存儲(chǔ)過(guò)程的若干問(wèn)題備忘在Oracle中,數(shù)據(jù)表別名不能加as。如:select
a.appname
from
appinfo
a;--正確
select
a.appname
from
appinfo
as
a;--錯(cuò)誤
也許,是怕和Oracle中的存儲(chǔ)過(guò)程中的關(guān)鍵字as沖突的問(wèn)題吧在存儲(chǔ)過(guò)程中,select某一字段時(shí),后面必須緊跟into,如果select整個(gè)記錄,利用游標(biāo)的話(huà)就另當(dāng)別論了。
select
af.keynode
into
kn
from
APPFOUNDATION
afwhere
af.appid=aid
and
af.foundationid=fid;--
有into,正確編譯select
af.keynode
from
APPFOUNDATION
af
where
af.appid=aid
and
af.foundationid=fid;--
沒(méi)有into,編譯報(bào)錯(cuò),提示:Compilation
Error:
PLS-00428:
an
INTO
clause
is
expected
in
this
SELECT
statement在利用o...語(yǔ)法時(shí),必須先確保數(shù)據(jù)庫(kù)中有該條記錄,否則會(huì)報(bào)出"nodatafound"異常??梢栽谠撜Z(yǔ)法之前,先利用selectcount(*)from查看數(shù)據(jù)庫(kù)中是否存在該記錄,如果存在,再利用o...在存儲(chǔ)過(guò)程中,別名不能和字段名稱(chēng)相同,否則雖然編譯可以通過(guò),但在運(yùn)行階段會(huì)報(bào)錯(cuò)
select
keynode
into
kn
from
APPFOUNDATION
where
appid=aid
and
foundationid=fid;--
正確運(yùn)行select
af.keynode
into
kn
from
APPFOUNDATION
af
where
af.appid=appid
and
af.foundationid=foundationid; --
運(yùn)行階段報(bào)錯(cuò),提示:
ORA-01422:exact
fetch
returns
more
than
requested
number
of
rows在存儲(chǔ)過(guò)程中,關(guān)于出現(xiàn)null的問(wèn)題假設(shè)有一個(gè)表A,定義如下:create
table
A(
id
varchar2(50)
primary
key
not
null,
vcount
number(8)
not
null,
bid
varchar2(50)
not
null
--
外鍵
);如果在存儲(chǔ)過(guò)程中,使用如下語(yǔ)句:select
sum(vcount)
into
fcount
from
A
where
bid='xxxxxx';如果A表中不存在bid="xxxxxx"的記錄,則fcount=null(即使fcount定義時(shí)設(shè)置了默認(rèn)值,如:fcountnumber(8):=0依然無(wú)效,fcount還是會(huì)變成null),這樣以后使用fcount時(shí)就可能有問(wèn)題,所以在這里最好先判斷一下:if
fcount
is
null
then
fcount:=0;
end
if;這樣就一切ok了。Hibernate調(diào)用Oracle存儲(chǔ)過(guò)程this.pnumberManager.getHibernateTemplate().execute(newHibernateCallback()...{publicObjectdoInHibernate(Sessionsession)throwsHibernateException,SQLException...{CallableStatementcs=session.connection().prepareCall("{callmodifyapppnumber_remain(?)}");cs.setString(1,foundationid);cs.execute();returnnull;}});用Java調(diào)用Oracle存儲(chǔ)過(guò)程總結(jié)無(wú)返回值的存儲(chǔ)過(guò)程測(cè)試表:--CreatetablecreatetableTESTTB(IDVARCHAR2(30),NAMEVARCHAR2(30))tablespaceBOMpctfree10initrans1maxtrans255storage(initial64Kminextents1maxextentsunlimited);例:存儲(chǔ)過(guò)程為(當(dāng)然了,這就先要求要建張表TESTTB,里面兩個(gè)字段(I_ID,I_NAME)。):CREATEORREPLACEPROCEDURETESTA(PARA1INVARCHAR2,PARA2INVARCHAR2)ASBEGININSERTINTOBOM.TESTTB(ID,NAME)VALUES(PARA1,PARA2);ENDTESTA;在Java里調(diào)用時(shí)就用下面的代碼:packagecedure.test;importjava.sql.CallableStatement;importjava.sql.Connection;importjava.sql.DriverManager;importjava.sql.ResultSet;importjava.sql.SQLException;importjava.sql.Statement;publicclassTestProcedureDemo1{ publicTestProcedureDemo1(){ } publicstaticvoidmain(String[]args){ Stringdriver="Oracle.jdbc.driver.OracleDriver"; StringstrUrl="jdbc:Oracle:thin:@0:1521:vasms"; Statementstmt=null; ResultSetrs=null; Connectionconn=null; CallableStatementproc=null; try{ Class.forName(driver); conn=DriverManager.getConnection(strUrl,"bom","bom"); proc=conn.prepareCall("{callBOM.TESTA(?,?)}"); proc.setString(1,"100"); proc.setString(2,"TestOne"); proc.execute(); }catch(SQLExceptionex2){ ex2.printStackTrace(); }catch(Exceptionex2){ ex2.printStackTrace(); }finally{ try{ if(rs!=null){ rs.close(); if(stmt!=null){ stmt.close(); } if(conn!=null){ conn.close(); } } }catch(SQLExceptionex1){ } } }}有返回值的存儲(chǔ)過(guò)程(非列表)例:存儲(chǔ)過(guò)程為:CREATEORREPLACEPROCEDURETESTB(PARA1INVARCHAR2,PARA2OUTVARCHAR2)ASBEGINSELECTNAMEINTOPARA2FROMTESTTBWHEREID=PARA1;ENDTESTB;在Java里調(diào)用時(shí)就用下面的代碼:packagecedure.test;importjava.sql.CallableStatement;importjava.sql.Connection;importjava.sql.DriverManager;importjava.sql.ResultSet;importjava.sql.SQLException;importjava.sql.Statement;importjava.sql.Types;publicclassTestProcedureDemo2{ publicstaticvoidmain(String[]args){ Stringdriver="Oracle.jdbc.driver.OracleDriver"; StringstrUrl="jdbc:Oracle:thin:@0:1521:vasms"; Statementstmt=null; ResultSetrs=null; Connectionconn=null; CallableStatementproc=null; try{ Class.forName(driver); conn=DriverManager.getConnection(strUrl,"bom","bom"); proc=conn.prepareCall("{callBOM.TESTB(?,?)}"); proc.setString(1,"100"); proc.registerOutParameter(2,Types.VARCHAR); proc.execute(); StringtestPrint=proc.getString(2); System.out.println("=testPrint=is="+testPrint); }catch(SQLExceptionex2){ ex2.printStackTrace(); }catch(Exceptionex2){ ex2.printStackTrace(); }finally{ try{ if(rs!=null){ rs.close(); if(stmt!=null){ stmt.close(); } if(conn!=null){ conn.close(); } } }catch(SQLExceptionex1){ } } }}注意,這里的proc.getString(2)中的數(shù)值2并非任意的,而是和存儲(chǔ)過(guò)程中的out列對(duì)應(yīng)的,如果out是在第一個(gè)位置,那就是proc.getString(1),如果是第三個(gè)位置,就是proc.getString(3),當(dāng)然也可以同時(shí)有多個(gè)返回值,那就是再多加幾個(gè)out參數(shù)了。返回列表由于Oracle存儲(chǔ)過(guò)程沒(méi)有返回值,它的所有返回值都是通過(guò)out參數(shù)來(lái)替代的,列表同樣也不例外,但由于是集合,所以不能用一般的參數(shù),必須要用pagkage了.所以要分兩部分,建一個(gè)程序包。如下:CREATEORREPLACEPACKAGETESTPACKAGEASTYPETEST_CURSORISREFCURSOR;endTESTPACKAGE;建立存儲(chǔ)過(guò)程,存儲(chǔ)過(guò)程為:CREATEORREPLACEPROCEDURETESTC(P_CURSORoutTESTPACKAGE.TEST_CURSOR)ISBEGINOPENP_CURSORFORSELECT*FROMBOM.TESTTB;ENDTESTC;可以看到,它是把游標(biāo)(可以理解為一個(gè)指針),作為一個(gè)out參數(shù)來(lái)返回值的。在Java里調(diào)用時(shí)就用下面的代碼:在這里要注意,在執(zhí)行前一定要先把Oracle的驅(qū)動(dòng)包放到class路徑里,否則會(huì)報(bào)錯(cuò)的。packagecedure.test;importjava.sql.CallableStatement;importjava.sql.Connection;importjava.sql.DriverManager;importjava.sql.ResultSet;importjava.sql.SQLException;importjava.sql.Statement;publicclassTestProcedureDemo3{ publicstaticvoidmain(String[]args){ Stringdriver="Oracle.jdbc.driver.OracleDriver"; StringstrUrl="jdbc:Oracle:thin:@0:1521:vasms"; Statementstmt=null; ResultSetrs=null; Connectionconn=null; CallableStatementproc=null; try{ Class.forName(driver); conn=DriverManager.getConnection(strUrl,"bom","bom"); proc=conn.prepareCall("{callbom.testc(?)}"); proc.registerOutParameter(1,Oracle.jdbc.OracleTypes.CURSOR); proc.execute(); rs=(ResultSet)proc.getObject(1); while(rs.next()){ System.out.println("<tr><td>"+rs.getString(1)+"</td><td>" +rs.getString(2)+"</td></tr>"); } }catch(SQLExceptionex2){ ex2.printStackTrace(); }catch(Exceptionex2){ ex2.printStackTrace(); }finally{ try{ if(rs!=null){ rs.close(); if(stmt!=null){ stmt.close(); } if(conn!=null){ conn.close(); } } }catch(SQLExceptionex1){ } } }}在存儲(chǔ)過(guò)程中做簡(jiǎn)單動(dòng)態(tài)查詢(xún)?cè)诖鎯?chǔ)過(guò)程中做簡(jiǎn)單動(dòng)態(tài)查詢(xún)代碼
,例如:CREATEORREPLACEprocedureZXM_SB_GZ_GET
(p_tableinvarchar2,
p_nameinvarchar2,
p_valueinvarchar2,
outparaoutlntxdba.zxm_pag_cs_power.c_type
)
as
begin
declare
wherevaluevarchar2(200);
begin
wherevalue:=select*from||p_table||where||p_name||=||p_value;
openoutparafor
wherevalue;
end;
end;一般的PL/SQL程序設(shè)計(jì)中,在DML和事務(wù)控制的語(yǔ)句中可以直接使用SQL,但是DDL語(yǔ)句及系統(tǒng)控制語(yǔ)句卻不能在PL/SQL中直接使用,要想實(shí)現(xiàn)在PL/SQL中使用DDL語(yǔ)句及系統(tǒng)控制語(yǔ)句,可以通過(guò)使用動(dòng)態(tài)SQL來(lái)實(shí)現(xiàn)。首先我們應(yīng)該了解什么是動(dòng)態(tài)SQL,在Oracle數(shù)據(jù)庫(kù)開(kāi)發(fā)PL/SQL塊中我們使用的SQL分為:靜態(tài)SQL語(yǔ)句和動(dòng)態(tài)SQL語(yǔ)句。所謂靜態(tài)SQL指在PL/SQL塊中使用的SQL語(yǔ)句在編譯時(shí)是明確的,執(zhí)行的是確定對(duì)象。而動(dòng)態(tài)SQL是指在PL/SQL塊編譯時(shí)SQL語(yǔ)句是不確定的,如根據(jù)用戶(hù)輸入的參數(shù)的不同而執(zhí)行不同的操作。編譯程序?qū)?dòng)態(tài)語(yǔ)句部分不進(jìn)行處理,只是在程序運(yùn)行時(shí)動(dòng)態(tài)地創(chuàng)建語(yǔ)句、對(duì)語(yǔ)句進(jìn)行語(yǔ)法分析并執(zhí)行該語(yǔ)句。Oracle中動(dòng)態(tài)SQL可以通過(guò)本地動(dòng)態(tài)SQL來(lái)執(zhí)行,也可以通過(guò)DBMS_SQL包來(lái)執(zhí)行。下面就這兩種情況分別進(jìn)行說(shuō)明:本地動(dòng)態(tài)SQL本地動(dòng)態(tài)SQL是使用EXECUTEIMMEDIATE語(yǔ)句來(lái)實(shí)現(xiàn)的。本地動(dòng)態(tài)SQL執(zhí)行DDL語(yǔ)句:需求:根據(jù)用戶(hù)輸入的表名及字段名等參數(shù)動(dòng)態(tài)建表。createorreplaceprocedureproc_test
(
table_nameinvarchar2,
--表名
field1invarchar2,
--字段名
datatype1invarchar2,
--字段類(lèi)型
field2invarchar2,
--字段名
datatype2invarchar2
--字段類(lèi)型
)as
str_sqlvarchar2(500);
begin
str_sql:=’createtable’||table_name||’(’||field1||’’||datatype1||’,’||field2||’’||datatype2||’)’;
executeimmediatestr_sql;
--動(dòng)態(tài)執(zhí)行DDL語(yǔ)句
exception
whenothersthen
null;
end;以上是編譯通過(guò)的存儲(chǔ)過(guò)程代碼。下面執(zhí)行存儲(chǔ)過(guò)程動(dòng)態(tài)建表。SQL>executeproc_test(’dinya_test’,’id’,’number(8)notnull’,’name’,’varchar2(100)’);
PL/SQLproceduresuccessfullycompleted
SQL>descdinya_test;
NameType
NullableDefaultComments
ID
NUMBER(8)
NAMEVARCHAR2(100)Y
SQL>到這里,就實(shí)現(xiàn)了我們的需求,使用本地動(dòng)態(tài)SQL根據(jù)用戶(hù)輸入的表名及字段名、字段類(lèi)型等參數(shù)來(lái)實(shí)現(xiàn)動(dòng)態(tài)執(zhí)行DDL語(yǔ)句。本地動(dòng)態(tài)SQL執(zhí)行DML語(yǔ)句。需求:將用戶(hù)輸入的值插入到上例中建好的dinya_test表中。createorreplaceprocedureproc_insert
(
idinnumber,
--輸入序號(hào)
nameinvarchar2
--輸入姓名
)as
str_sqlvarchar2(500);
begin
str_sql:=’insertintodinya_testvalues(:1,:2)’;
executeimmediatestr_sqlusingid,name;--動(dòng)態(tài)執(zhí)行插入操作
exception
whenothersthen
null;
end;
執(zhí)行存儲(chǔ)過(guò)程,插入數(shù)據(jù)到測(cè)試表中。SQL>executeproc_insert(1,’dinya’);
PL/SQLproceduresuccessfullycompleted
SQL>select*fromdinya_test;
ID
NAME
1
dinya在上例中,本地動(dòng)態(tài)SQL執(zhí)行DML語(yǔ)句時(shí)使用了using子句,按順序?qū)⑤斎氲闹到壎ǖ阶兞浚绻枰敵鰠?shù),可以在執(zhí)行動(dòng)態(tài)SQL的時(shí)候,使用RETURNINGINTO子句,如:declare
p_idnumber:=1;
v_countnumber;
begin
v_string:=’selectcount(*)fromtable_nameawherea.id=:id’;
executeimmediatev_stringintov_countusingp_id;
end;使用DBMS_SQL包使用DBMS_SQL包實(shí)現(xiàn)動(dòng)態(tài)SQL的步驟如下:A、先將要執(zhí)行的SQL語(yǔ)句或一個(gè)語(yǔ)句塊放到一個(gè)字符串變量中。B、使用DBMS_SQL包的parse過(guò)程來(lái)分析該字符串。C、使用DBMS_SQL包的bind_variable過(guò)程來(lái)綁定變量。D、使用DBMS_SQL包的execute函數(shù)來(lái)執(zhí)行語(yǔ)句。1、使用DBMS_SQL包執(zhí)行DDL語(yǔ)句需求:使用DBMS_SQL包根據(jù)用戶(hù)輸入的表名、字段名及字段類(lèi)型建表。createorreplaceprocedureproc_dbms_sql
(
table_nameinvarchar2,
--表名
field_name1invarchar2,
--字段名
datatype1invarchar2,
--字段類(lèi)型
field_name2invarchar2,
--字段名
datatype2invarchar2
--字段類(lèi)型
)as
v_cursornumber;
--定義光標(biāo)
v_stringvarchar2(200);
--定義字符串變量
v_rownumber;
--行數(shù)
begin
v_cursor:=dbms_sql.open_cursor;
--為處理打開(kāi)光標(biāo)
v_string:=’createtable’||table_name||’(’||field_name1||’’||datatype1||’,’||field_name2||’’||datatype2||’)’;
dbms_sql.parse(v_cursor,v_string,dbms_sql.native);
--分析語(yǔ)句
v_row:=dbms_sql.execute(v_cursor);
--執(zhí)行語(yǔ)句
dbms_sql.close_cursor(v_cursor);
--關(guān)閉光標(biāo)
exception
whenothersthen
dbms_sql.close_cursor(v_cursor);
--關(guān)閉光標(biāo)
raise;
end;以上過(guò)程編譯通過(guò)后,執(zhí)行過(guò)程創(chuàng)建表結(jié)構(gòu):SQL>executeproc_dbms_sql(’dinya_test2’,’id’,’number(8)notnull’,’name’,’varchar2(100)’);
PL/SQLproceduresuccessfullycompleted
SQL>descdinya_test2;
NameType
NullableDefaultComments
ID
NUMBER(8)
NAMEVARCHAR2(100)Y
SQL>使用DBMS_SQL包執(zhí)行DML語(yǔ)句需求:使用DBMS_SQL包根據(jù)用戶(hù)輸入的值更新表中相對(duì)應(yīng)的記錄。查看表中已有記錄:SQL>select*fromdinya_test2;
IDNAME
1Oracle
2CSDN
3ERP
SQL>建存儲(chǔ)過(guò)程,并編譯通過(guò):createorreplaceprocedureproc_dbms_sql_update
(
idnumber,
namevarchar2
)as
v_cursornumber;
--定義光標(biāo)
v_stringvarchar2(200);
--字符串變量
v_rownumber;
--行數(shù)
begin
v_cursor:=dbms_sql.open_cursor;
--為處理打開(kāi)光標(biāo)
v_string:=’updatedinya_test2aset=:p_namewherea.id=:p_id’;
dbms_sql.parse(v_cursor,v_string,dbms_sql.native);
--分析語(yǔ)句
dbms_sql.bind_variable(v_cursor,’:p_name’,name);
--綁定變量
dbms_sql.bind_variable(v_cursor,’:p_id’,id);
--綁定變量
v_row:=dbms_sql.execute(v_cursor);--執(zhí)行動(dòng)態(tài)SQL
dbms_sql.close_cursor(v_cursor);
--關(guān)閉光標(biāo)
exception
whenothersthen
dbms_sql.close_cursor(v_cursor);
--關(guān)閉光標(biāo)
raise;
end;執(zhí)行過(guò)程,根據(jù)用戶(hù)輸入的參數(shù)更新表中的數(shù)據(jù):SQL>executeproc_dbms_sql_update(2,’csdn_dinya’);
PL/SQLproceduresuccessfullycompleted
SQL>select*fromdinya_test2;
IDNAME
1Oracle
2csdn_dinya
3ERP
SQL>執(zhí)行過(guò)程后將第二條的name字段的數(shù)據(jù)更新為新值csdn_dinya。這樣就完成了使用dbms_sql包來(lái)執(zhí)行DML語(yǔ)句的功能。使用DBMS_SQL中,如果要執(zhí)行的動(dòng)態(tài)語(yǔ)句不是查詢(xún)語(yǔ)句,使用DBMS_SQL.Execute或DBMS_SQL.Variable_Value來(lái)執(zhí)行,如果要執(zhí)行動(dòng)態(tài)語(yǔ)句是查詢(xún)語(yǔ)句,則要使用DBMS_SQL.define_column定義輸出變量,然后使用DBMS_SQL.Execute,DBMS_SQL.Fetch_Rows,DBMS_SQL.Column_Value及DBMS_SQL.Variable_Value來(lái)執(zhí)行查詢(xún)并得到結(jié)果。總結(jié)說(shuō)明:在Oracle開(kāi)發(fā)過(guò)程中,我們可以使用動(dòng)態(tài)SQL來(lái)執(zhí)行DDL語(yǔ)句、DML語(yǔ)句、事務(wù)控制語(yǔ)句及系統(tǒng)控制語(yǔ)句。但是需要注意的是,PL/SQL塊中使用動(dòng)態(tài)SQL執(zhí)行DDL語(yǔ)句的時(shí)候與別的不同,在DDL中使用綁定變量是非法的(bind_variable(v_cursor,’:p_name’,name)),分析后不需要執(zhí)行DBMS_SQL.Bind_Variable,直接將輸入的變量加到字符串中即可。另外,DDL是在調(diào)用DBMS_SQL.PARSE時(shí)執(zhí)行的,所以DBMS_SQL.EXECUTE也可以不用,即在上例中的v_row:=dbms_sql.execute(v_cursor)部分可以不要。Oracle存儲(chǔ)過(guò)程調(diào)用Java方法存儲(chǔ)過(guò)程中調(diào)用Java程序段軟件環(huán)境:操作系統(tǒng):Windows
2000
Server數(shù)
據(jù)
庫(kù):\o"搜索該標(biāo)簽相關(guān)文章"Oracle
8i
R2
(8.1.7)
for
NT
企業(yè)版安裝路徑:C:\ORACLE實(shí)現(xiàn)方法:創(chuàng)建一個(gè)文件為T(mén)est.javapublicclassTest{ publicstaticvoidmain(Stringargs[]){ System.out.println("HELLOTHISiSAJavaPROCEDURE"); }}javac
Test.javajava
TestSQL>
conn
system/managerSQL>
grant
create
any
directory
to
scott;SQL>
conn
scott/tigerSQL>
create
or
replace
directory
test_dir
as
'd:\';目錄已創(chuàng)建。SQL>
create
or
replace
java
class
using
bfile(test_dir,'TEST.CLASS')2
/Java
已創(chuàng)建。SQL>
select
object_name,object_type,STATUS
from
user_objects;SQL>
create
or
replace
procedure
test_javaas
language
javaname
'TEST.main(java.lang.String[])';/過(guò)程已創(chuàng)建。SQL>
set
serveroutput
on
size
5000SQL>
call
dbms_java.set_output(5000);調(diào)用完成。SQL>
execute
test_java;H
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶(hù)所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶(hù)上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶(hù)上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶(hù)因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 作協(xié)議合同范本
- 關(guān)于管道疏通合同范本
- 別墅弱電智能合同范本
- 產(chǎn)品合同范本模板寫(xiě)
- 農(nóng)資代理合同范本
- 上海小時(shí)工外包合同范本
- 個(gè)人續(xù)簽合同范本
- 農(nóng)村開(kāi)發(fā)項(xiàng)目合同范本
- 寫(xiě)電子產(chǎn)品合同范本
- 平面設(shè)計(jì)創(chuàng)意與制作課件
- 化學(xué)專(zhuān)業(yè)英語(yǔ)元素周期表
- 新湘版小學(xué)科學(xué)四年級(jí)下冊(cè)教案(全冊(cè))
- Q∕SY 06349-2019 油氣輸送管道線路工程施工技術(shù)規(guī)范
- CEO自戀及其經(jīng)濟(jì)后果研究:以格力電器為例
- 腎內(nèi)科臨床診療規(guī)范(南方醫(yī)院)
- 實(shí)驗(yàn)心理學(xué)課件(周愛(ài)保博士版)
- 04 第三章 環(huán)境污染物的生物轉(zhuǎn)運(yùn)和生物轉(zhuǎn)化 -毒物動(dòng)力學(xué)
- 珍愛(ài)生命 安全第一 中小學(xué)主題教育班會(huì)
- 殺蟲(chóng)雙(單)合成反應(yīng)的研究及其工藝條件的優(yōu)化
- 膨脹螺栓選型計(jì)算_20160606
評(píng)論
0/150
提交評(píng)論