动态游标里不能使用变量吗?
我建了个存储过程,因为所取列是变化的,所以应用了动态游标,但现在出现一个问题,在运行动态游标时报错,错误提示“ora-00904 "end_date " invalid identifier ",我已经试过了,如果采用普通游标end_date 变量是没问题的,感觉是执行动态游标时数据库没把end_date作为一个变量来识别,不知是不是动态游标里不能再使用变量,请各位大虾解答。
create or replace procedure p_search_client_month_sale
(st_date in date,
end_date in date) is
new_st_date date;
new_sql varchar2(4000);
-- new_sql varchar2(4000); --用于保存最终执行的sql语句
type cur is ref cursor; --定义动态游标变量
col cur;
/*以下开始procedure执行*/
--获得转换交叉表sql
declare one_col varchar2(200); --存储每1列的sql语句
col_sql varchar2(4000); --存储所有列sql语句
cur_sql varchar2(1000); --动态游标构造sql
begin
cur_sql := 'select '|| ' ' ',nvl((select sum( usercount) from cq_tmp_sale_data where clientcls=a.clientcls and orddate = ' '|| '|| 'orddate ' || '|| ' '),0) as '|| ' " ' '|| '|| 'orddate ' || '|| ' ' " ' ' '
|| ' from cq_tmp_sale_data '
|| ' where orddate between to_char(st_date, '|| ' ' 'yyyymm ' ' '|| ') and to_char(end_date, '|| ' ' 'yyyymm ' ' '|| ') '
|| ' group by orddate ';
open col for cur_sql;
loop
fetch col into one_col;
exit when col%notfound;
col_sql := col_sql || one_col ;
end loop;
close col;
--dbms_output.put_line(col_sql);
new_sql:= 'select clientcls,1 as usercount ' || col_sql ||
' from cq_tmp_sale_data a where a.orddate between '
|| to_char(st_date, 'yyyymm ') || ' and '|| to_char(end_date, 'yyyymm ') || ' group by clientcls ';
--execute immediate new_sql;
end ;
end p_search_client_month_sale;
[解决办法]
使用动态游标时请注意自己的动态sql,你的cur_sql内容为:
select ',nvl((select sum( usercount) from cq_tmp_sale_data where clientcls=a.clientcls and orddate = '||orddate|| '),0) as " '||orddate|| ' " ' from cq_tmp_sale_data where orddate between to_char(st_date, 'yyyymm ') and to_char(end_date, 'yyyymm ') group by orddate
这样的sql是不可能执行的
关于动态sql的帮定变量应该这样:
declare
type myc is type of ref coursor;
var_sql varchar2(8000);
var_1 varchar2(20);
var_2 varchar2(20);
myc1 myc;
begin
...
var_sql := 'select col1 from table where table.col2 = :var1 and table.col3 = :var2 ';
open myc1 for var_sql using var_1,var_2;
...
end;
[解决办法]
sql 书写上的问题,在open前你把cur_sql打印出来执行一下 看看是否可以执行,然后再继续...
[解决办法]
execute immediate
结果在服务端,dev里是客户端.