動態存儲過程
exec('select top '+@PageSize+' * from Books where Title like 『』'+@Title+'『』and Id not in (select top '+@Page+' Id from Books where Title like『』'+@Title+'『』 order by '+@Order+') order by '+@Order)
兩個 like 附近需要用單引號括起來。
『貳』 如何動態執行存儲過程或函數
您好,很高興為您解答。
/*動態執行存儲過程DEMO*/
DECLARE
v_Procere_Name VARCHAR2(320); --存儲過程名
v_Input_Parameter1 VARCHAR2(320); --傳入參數1
v_Input_Parameter2 VARCHAR2(320); --傳入參數2
v_Return_Int INTEGER; --接收返回值
v_Return_String VARCHAR2(320); --接收返回值
v_Sql_Str VARCHAR2(320); --動態執行SQL語句
BEGIN
/*獲取存儲過程名,可以從資料庫中動態讀取需要執行的存儲過程,本DEMO直接賦值*/
v_Procere_Name := 'Wms_Application_Out_p.Application_Out_List_Refuse(:i_Str1,:i_Str2,_Return_Int,_Return_String)';
/*本DEMO假定需要調用的存儲過程有兩個傳入參數和兩個傳出參數*/
v_Input_Parameter1 := 'test01'; --傳入參數1,在實際應用中根據具體情況機型賦值
v_Input_Parameter2 := 'test01'; --傳入參數2,在實際應用中根據具體情況機型賦值
/*動態生成需要執行存儲過程的SQL語句*/
v_Sql_Str := 'BEGIN ' || v_Procere_Name || '; END;';
/*執行該SQL語句*/
EXECUTE IMMEDIATE v_Sql_Str
USING IN v_Input_Parameter1, IN v_Input_Parameter2, OUT v_Return_Int, OUT v_Return_String; --參數類型和傳遞順序必須與存儲過程中的保持一致
/*輸出返回值*/
Dbms_Output.Put_Line(v_Return_Int || v_Return_String);
END;
/*動態執行函數DEMO*/
DECLARE
v_Function_Name VARCHAR2(320); --函數名
v_Input_Parameter1 VARCHAR2(320); --傳入參數1
v_Return_String VARCHAR2(320); --接收返回值
v_Sql_Str VARCHAR2(320); --動態執行SQL語句
BEGIN
/*獲取函數名,可以從資料庫中動態讀取需要執行的函數,本DEMO直接賦值*/
v_Function_Name := 'Return_Str_f(:i_Str1)';
/*本DEMO假定需要調用的函數有1個傳入參數*/
v_Input_Parameter1 := 'test01'; --傳入參數1,在實際應用中根據具體情況機型賦值
/*動態生成需要執行函數的SQL語句*/
v_Sql_Str := 'begin :v_Return_String := ' || v_Function_Name || '; end;';
/*執行該SQL語句*/
EXECUTE IMMEDIATE v_Sql_Str
USING OUT v_Return_String, IN v_Input_Parameter1; --接收返回值必須在前,傳入參數類型和傳遞順序必須與函數中保持一致
/*輸出返回值*/
Dbms_Output.Put_Line(v_Return_String);
END;
/*所調用函數*/
CREATE OR REPLACE FUNCTION Return_Str_f(i_Str1 VARCHAR2) RETURN VARCHAR2 IS
v_Sql_Str VARCHAR2(320);
v_Str1 VARCHAR2(320);
BEGIN
/*生成動態執行SQL*/
v_Sql_Str := 'SELECT ''' || i_Str1 || ''' FROM DUAL';
EXECUTE IMMEDIATE v_Sql_Str
INTO v_Str1; --接收返回值
/*輸出返回結果*/
Dbms_Output.Put_Line('v_str1=' || v_Str1);
RETURN v_Str1;
END;
相關資料:
Oracle PL/SQL中動態執行SQL EXECUTE IMMEDIATE
在plsql中經常遇到sql語句是在過程中動態生成的,這個時候可以用EXECUTE IMMEDIATE來執行生成的sql語句。轉一個javaeye(貌似他也是轉的,找不到出處)上的EXECUTE IMMEDIATE用法。
EXECUTE IMMEDIATE代替了以前Oracle8i中DBMS_SQL package包.它解析並馬上執行動態的SQL語句或非運行時創建的PL/SQL塊.動態創建和執行SQL語句性能超前,EXECUTE IMMEDIATE的目標在於減小企業費用並獲得較高的性能,較之以前它相當輕易編碼.盡管DBMS_SQL仍然可用,
但是推薦使用EXECUTE IMMEDIATE,因為它獲的收益在包之上。
使用技巧
1. EXECUTE IMMEDIATE將不會提交一個DML事務執行,應該顯式提交
假如通過EXECUTE IMMEDIATE處理DML命令,那麼在完成以前需要顯式提交或者作為EXECUTE IMMEDIATE自己的一部分. 假如通過EXECUTE IMMEDIATE處理DDL命令,它提交所有以前改變的數據
2. 不支持返回多行的查詢,這種交互將用臨時表來存儲記錄(參照例子如下)或者用REF cursors.
3. 當執行SQL語句時,不要用分號,當執行PL/SQL塊時,在其尾部用分號.
4. 在Oracle手冊中,未具體覆蓋這些功能。下面的例子展示了所有用到Execute immediate的可能方面.希望能給你帶來方便.
5. 對於Forms開發者,當在PL/SQL 8.0.6.3.版本中,Forms 6i不能使用此功能.
EXECUTE IMMEDIATE用法例子
1. 在PL/SQL運行DDL語句
begin
execute immediate 'set role all';
end;
2. 給動態語句傳值(USING 子句)
declare
l_depnam varchar2(20) := 'testing';
l_locvarchar2(10) := 'Du';
begin
execute immediate 'insert into dept values(:1, :2, :3)'
using 50, l_depnam, l_loc;
commit;
end;
3. 從動態語句檢索值(INTO子句)
declare
l_cntvarchar2(20);
begin
execute immediate 'select count(1) from emp'
into l_cnt;
dbms_output.put_line(l_cnt);
end;
4. 動態調用常式.常式中用到的綁定變數參數必須指定參數類型.黓認為IN類型,其它類型必須顯式指定
declare
l_routin varchar2(100) := 'gen2161.get_rowcnt';
l_tblnam varchar2(20) := 'emp';
l_cntnumber;
l_status varchar2(200);
begin
execute immediate 'begin ' l_routin '(:2, :3, :4); end;'
using in l_tblnam, out l_cnt, in out l_status;
if l_status != 'OK' then
dbms_output.put_line('error');
end if;
end;
5. 將返回值傳遞到PL/SQL記錄類型;同樣也可用%rowtype變數
declare
type empdtlrec is record (empnonumber(4),
enamevarchar2(20),
deptnonumber(2));
empdtl empdtlrec;
begin
execute immediate 'select empno, ename, deptno '
'from emp where empno = 7934'
into empdtl;
end;
6. 傳遞並檢索值.INTO子句用在USING子句前
declare
l_deptpls_integer := 20;
l_nam varchar2(20);
l_loc varchar2(20);
begin
execute immediate 'select dname, loc from dept where deptno = :1'
into l_nam, l_loc
using l_dept ;
end;
7. 多行查詢選項.對此選項用insert語句填充臨時表,用臨時表進行進一步的處理,也可以用REF cursors糾正此缺憾.
declare
l_sal pls_integer := 2000;
begin
execute immediate 'insert into temp(empno, ename) '
'select empno, ename from emp '
'wheresal :1'
using l_sal;
commit;
end;
對於處理動態語句,EXECUTE IMMEDIATE比以前可能用到的更輕易並且更高效.當意圖執行動態語句時,適當地處理異常更加重要.應該關注於捕捉所有可能的異常.
如若滿意,請點擊右側【採納答案】,如若還有問題,請點擊【追問】
希望我的回答對您有所幫助,望採納!
~ O(∩_∩)O~
『叄』 oracle動態存儲過程錯誤100不夠++急等
declare
userid number;
str varchar2(50);
begin
select t2.hot_ntid hot_ntid
,t2.hot_ntseq hot_ntseq
,t2.hot_nttitle hot_nttitle
,t2.hot_crtuser hot_crtuser
,t2.hot_startdate hot_startdate
,t1.hot_rdid hot_rdid
,t2.hot_urlevel hot_urlevel
from hot_notice2users t1
,hot_notices t2
where t1.hot_ntid =t2.hot_ntid
and t1.hot_status = 0
and t2.hot_orgid = 0
and t2.HOT_URLEVEL = str
and t1.hot_readerid = userid;
end ;
語法上是這樣的
但是你這樣沒有什麼意義吧,沒有輸出呀,也沒操作資料庫,只是把數據查出來還沒有顯示呢
下面這樣可以有輸出,結果會顯示在output頁
declare
userid number;
str varchar2(50);
cursor c_cur is
select t2.hot_ntid hot_ntid
,t2.hot_ntseq hot_ntseq
,t2.hot_nttitle hot_nttitle
,t2.hot_crtuser hot_crtuser
,t2.hot_startdate hot_startdate
,t1.hot_rdid hot_rdid
,t2.hot_urlevel hot_urlevel
from hot_notice2users t1
,hot_notices t2
where t1.hot_ntid =t2.hot_ntid
and t1.hot_status = 0
and t2.hot_orgid = 0
and t2.HOT_URLEVEL = str
and t1.hot_readerid = userid;
begin
FOR c1 IN c_cur
LOOP
dbms_output.put_line(c1.hot_ntid);
dbms_output.put_line(c1.hot_ntseq);
dbms_output.put_line(c1.hot_nttitle);
dbms_output.put_line(c1.hot_crtuser);
dbms_output.put_line(c1.hot_startdate);
dbms_output.put_line(c1.hot_rdid);
dbms_output.put_line(c1.hot_urlevel);
end loop;
end ;