首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 数据库 > oracle >

参数游标的有关问题

2012-07-24 
求一个参数游标的问题各位大侠:我最近在写一个存储过程,具体的作用是每天把前一天的入库的记录数统计一下,

求一个参数游标的问题
各位大侠:
  我最近在写一个存储过程,具体的作用是每天把前一天的入库的记录数统计一下,然后和再前一天的比较一下,以此判断每天的入库进程是否正常。
我的数据库是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;                  RAISE;    end   SP_CLEAR; 

热点排行