求一个参数游标的问题
各位大侠:
我最近在写一个存储过程,具体的作用是每天把前一天的入库的记录数统计一下,然后和再前一天的比较一下,以此判断每天的入库进程是否正常。
我的数据库是Oracle9i Enterprise Edition Release 9.2.0.4.0
运行在AIX5.2的系统上。
现在写到一半,遇到一个问题,是关于参数游标的。
create or replace procedure p_wk_xdjk2
AS
v_smscontent varchar2(200) :='';
v_date varchar2(8);
v_date_before varchar2(8);
v_yyyy1 varchar2(4);
v_yy1 varchar2(2);
v_mm1 varchar2(2);
v_dd1 varchar2(2);
v_yyyy2 varchar2(4);
v_yy2 varchar2(2);
v_mm2 varchar2(2);
v_dd2 varchar2(2);
CURSOR c_jk (v_mma IN varchar2,v_dda IN varchar2,v_mmb IN varchar2,v_ddb IN varchar2) IS
SELECT A.ZS,DECODE(TRUNC(ROUND((A.ZS-B.ZS)/B.ZS*100,2)),0,REPLACE(ROUND((A.ZS-B.ZS)/B.ZS*100,2),'0','0.'),TRUNC(ROUND((A.ZS-B.ZS)/B.ZS*100,2)))||'%' TBZR
FROM (SELECT COUNT(*) ZS FROM TG_CDR03_FIX_REAL PARTITION(P03)) A,(SELECT COUNT(*) ZS FROM TG_CDR03_FIX_REAL PARTITION(P01)) B;
vr_jk c_jk%ROWTYPE;
BEGIN
SELECT to_char(sysdate,'yyyy'),to_char(sysdate,'yy'),to_char(sysdate,'mm'),to_char(sysdate,'dd'),to_char(sysdate-1,'yyyy'),to_char(sysdate-1,'yy'),to_char(sysdate-1,'mm'),to_char(sysdate-1,'dd') into v_yyyy1, v_yy1,v_mm1,v_dd1,v_yyyy2, v_yy2,v_mm2,v_dd2 from dual;
OPEN c_jk(v_mm1,v_dd1,v_mm2,v_dd2);
LOOP
FETCH c_jk INTO vr_jk;
EXIT WHEN c_jk%NOTFOUND;
v_smscontent := v_smscontent||v_dd2 ||vr_jk.ZS||':'||vr_jk.TBZR||';';
END LOOP;
v_smscontent := ''||'日:'||' '||v_smscontent;
CLOSE c_jk;
insert into jzl_smsyx_ss@wkibm VALUES('13000000000',v_smscontent,'WK');
commit;/*插入短信*/
EXCEPTION
WHEN OTHERS THEN
ROLLBACK;
insert into jzl_smsyx_ss@wkibm VALUES ('13000000000','详单监控存储过程失败。','WK');
commit;
END;
如各位所见,其余部分都可以不管,关键是我写的那个游标。
CURSOR c_jk (v_mma IN varchar2,v_dda IN varchar2,v_mmb IN varchar2,v_ddb IN varchar2) IS
SELECT A.ZS,DECODE(TRUNC(ROUND((A.ZS-B.ZS)/B.ZS*100,2)),0,REPLACE(ROUND((A.ZS-B.ZS)/B.ZS*100,2),'0','0.'),TRUNC(ROUND((A.ZS-B.ZS)/B.ZS*100,2)))||'%' TBZR
FROM (SELECT COUNT(*) ZS FROM TG_CDR03_FIX_REAL PARTITION(P02)) A,(SELECT COUNT(*) ZS FROM TG_CDR03_FIX_REAL PARTITION(P01)) B;
因为像TG_CDR03_FIX_REAL PARTITION(P02),这样的分区表,按我上面写的是没有问题的。可以顺利编译并执行成功。但是实际上,该表的03表示的是月份,而它是按日期来分区的。也就是说TG_CDR03_FIX_REAL PARTITION(P02)代表3月2日的入库量。所以我的游标必须要用参数变量来代替固定值,否则我就要每天重建我的存储过程。
现在的问题是TG_CDR03_FIX_REAL PARTITION(P02) 或者 TG_CDR03_FIX_REAL PARTITION(P01))这两个表名,当我用上面的参数v_mma IN varchar2,v_dda IN varchar2,v_mmb IN varchar2,v_ddb IN varchar2进行替代的时候,比如TG_CDRv_mma_FIX_REAL PARTITION(Pv_dda)存储过程能够编译成功,但是执行结果却是“详单监控存储过程失败”。
请各位大侠帮忙看看,因为我看到书上面的例子,游标是可以带参数的,不过例子中变量都是单独放在“=”符号的右侧的,像我这么写是不是不可以?
------解决方案--------------------
动态游标~!!!!
SQL code
create or replace procedure SP_CLEAR(V_TABLE IN STRING) IS
TYPE cur_type IS REF CURSOR;
c_tab cur_type;
v_str STRING(2000);
v_tab t_clear.wlbmc%TYPE;
v_sql STRING(3000);
begin
--Get table from v_table
--Reorder these tables
v_str:=upper(v_table);
v_str:=REPLACE(v_str,',',''',''');
v_str:=''''||v_str||'''';
v_sql:='SELECT WLBMC FROM T_CLEAR WHERE TRIM(WLBMC) IN ('||v_str||') ORDER BY BZ DESC';
OPEN c_tab FOR v_sql;
LOOP
FETCH c_tab INTO v_tab;
EXIT WHEN c_tab%NOTFOUND;
v_sql:='delete from '||v_tab||'';
EXECUTE IMMEDIATE v_sql;
END LOOP;
COMMIT;
--deal with exception
EXCEPTION
WHEN OTHERS THEN
ROLLBACK;
RAIS