您的位置:首页 > 数据库 > Oracle

Oracle817与Oracle7.3.4存储过程动态游标的区别

2008-01-23 17:21 351 查看
Oracle817下存储过程改成Oracle7下,由于Oracle7下不支持OPEN CUR_1 FOR strSql1;--打开bill_tj_out的动态游标的写法,采用CUR_1 := dbms_sql.open_cursor; --打开游标;方式打开游标。

下面的两个存储过程有相同的功能。

Oracle817下的动态游标存储过程如下:

CREATE OR REPLACE PROCEDURE Pro_Remain_Merge_Win
(
p_orgid_win string,--窗口的ID号
p_userid string
)
is
TYPE My_CurType IS REF CURSOR;
CUR_1 My_CurType;--指示CUR_1的类型为My_CurType,而My_CurType是游标类型
CUR_2 My_CurType;--指示CUR_1的类型为My_CurType,而My_CurType是游标类型

strSql1 varchar2(3000);
strSql2 varchar2(3000);
strSql3 varchar2(3000);
t_bill_typeid number;--窗口发售的票据种类的ID号
t_orgid_zhan number;--窗口所在车站的ID号

--下面的为表合并时需要使用的临时变量

t_bill_id_1 number;
t_bill_typeid_1 number;
t_bill_sign_1 varchar2(12);
t_start_no_1 number;
t_end_no_1 number;
t_all_num_1 number;
t_bill_time_1 date;
t_bill_time_1_yyyy number;--bill_time中的年
t_bill_time_1_mm number;--bill_time中的有

--
t_bill_id_2 number;
t_bill_id_2_merge number;--在表bill_tj_out_a表中,找到的可以合并的记录的ID号
t_bill_typeid_2 number;
t_bill_sign_2 varchar2(12);
t_start_no_2 number;
t_end_no_2 number;
t_all_num_2 number;
t_bill_time_2 date;
t_bill_time_2_str varchar2(40);--日期的串格式,在更新时要使用
t_bill_time_2_yyyy number;--bill_time中的年
t_bill_time_2_mm number;--bill_time中的有
BEGIN

t_bill_id_2_merge:=0;--刚开始时的初始值

delete bill_tj_out_a where userid=p_userid;
commit;

--返回窗口使用的票据的种类
select nvl(bill_wintobilltype.billtypeid,0) into t_bill_typeid
from bill_org,bill_wintobilltype
where bill_org.org_id=bill_wintobilltype.winid
and bill_org.org_id=p_orgid_win;
--返回车站的ID号
select nvl(bill_org.parent_id,0) into t_orgid_zhan
from bill_org where org_id=p_orgid_win;

--execute dbms_output.enable(999999999999999999999);

strSql1:='SELECT bill_id,bill_typeid,bill_sign,start_no,end_no, all_num,bill_time FROM bill_tj_out WHERE userid='||p_userid
||' order by bill_sign,start_no,end_no';

strSql2:='SELECT bill_id,bill_typeid,bill_sign,start_no,end_no, all_num,bill_time FROM bill_tj_out_a WHERE userid='||p_userid
||' order by bill_sign,start_no';

delete bill_tj_out_a where userid=p_userid;
commit;

OPEN CUR_1 FOR strSql1;--打开bill_tj_out的动态游标
LOOP
FETCH CUR_1 INTO t_bill_id_1,t_bill_typeid_1,t_bill_sign_1,t_start_no_1,t_end_no_1,t_all_num_1,t_bill_time_1;
EXIT WHEN CUR_1%NOTFOUND;

select to_char(t_bill_time_1,'yyyy') into t_bill_time_1_yyyy from dual;--提取日期中的年
select to_char(t_bill_time_1,'mm') into t_bill_time_1_mm from dual;--提取日期中的月

OPEN CUR_2 FOR strSql2;--打开动态游标2
LOOP
FETCH CUR_2 INTO t_bill_id_2,t_bill_typeid_2,t_bill_sign_2,t_start_no_2,t_end_no_2,t_all_num_2,t_bill_time_2;
EXIT WHEN CUR_2%NOTFOUND;

select to_char(t_bill_time_2,'yyyy') into t_bill_time_2_yyyy from dual;--提取日期中的年
select to_char(t_bill_time_2,'mm') into t_bill_time_2_mm from dual;--提取日期中的月
if(t_bill_sign_1=t_bill_sign_2 and t_bill_typeid_1=t_bill_typeid_2 and t_bill_time_1_yyyy=t_bill_time_2_yyyy
and t_bill_time_1_mm=t_bill_time_2_mm and (t_end_no_2+1=t_start_no_1)) then
t_bill_id_2_merge:=t_bill_id_1;

end if;

END LOOP;
CLOSE CUR_2;
--判断是否可以合并。不可以合并则插入到bill_tj_out_a中
if t_bill_id_2_merge<>0 then

update bill_tj_out_a set bill_tj_out_a.bill_id=t_bill_id_1,end_no=t_end_no_1,bill_time=t_bill_time_1,all_num=all_num+t_all_num_1
where bill_id=t_bill_id_2 and userid=p_userid;
delete bill_tj_out where bill_id=t_bill_id_2_merge and userid=p_userid;
commit;
t_bill_id_2_merge:=0;
else
insert into bill_tj_out_a select * from bill_tj_out where userid=p_userid and bill_id=t_bill_id_1;
delete bill_tj_out where bill_id=t_bill_id_1 and userid=p_userid;

commit;
end if;
--t_bill_id_2_merge:=0;*/
close CUR_1;
OPEN CUR_1 FOR strSql1;

END LOOP;commit;
---下面重新计算结存数量

end Pro_Remain_Merge_Win;

Oracle7.3.4 下功能相同的存储过程写法:

CREATE OR REPLACE PROCEDURE Pro_Remain_Merge_Win_1
(
p_orgid_win string,--窗口的ID号
p_userid string
)
is
--TYPE My_CurType IS REF CURSOR;
CUR_1 number;--指示CUR_1的类型为My_CurType,而My_CurType是游标类型
CUR_2 number;--指示CUR_1的类型为My_CurType,而My_CurType是游标类型
Cur_1_return number;
strSql1 varchar2(3000);
strSql2 varchar2(3000);
strSql3 varchar2(3000);
t_bill_typeid number;--窗口发售的票据种类的ID号
t_orgid_zhan number;--窗口所在车站的ID号

--下面的为表合并时需要使用的临时变量

t_bill_id_1 number;
t_bill_typeid_1 number;
t_bill_sign_1 varchar2(12);
t_start_no_1 number;
t_end_no_1 number;
t_all_num_1 number;
t_bill_time_1 date;
t_bill_time_1_yyyy number;--bill_time中的年
t_bill_time_1_mm number;--bill_time中的有

--
t_bill_id_2 number;
t_bill_id_2_merge number;--在表bill_tj_out_a表中,找到的可以合并的记录的ID号
t_bill_typeid_2 number;
t_bill_sign_2 varchar2(12);
t_start_no_2 number;
t_end_no_2 number;
t_all_num_2 number;
t_bill_time_2 date;
t_bill_time_2_str varchar2(40);--日期的串格式,在更新时要使用
t_bill_time_2_yyyy number;--bill_time中的年
t_bill_time_2_mm number;--bill_time中的有
BEGIN

t_bill_id_2_merge:=0;--刚开始时的初始值

delete bill_tj_out_a where userid=p_userid;
commit;

--返回窗口使用的票据的种类
select nvl(bill_wintobilltype.billtypeid,0) into t_bill_typeid
from bill_org,bill_wintobilltype
where bill_org.org_id=bill_wintobilltype.winid
and bill_org.org_id=p_orgid_win;
--返回车站的ID号
select nvl(bill_org.parent_id,0) into t_orgid_zhan
from bill_org where org_id=p_orgid_win;

--execute dbms_output.enable(999999999999999999999);

strSql1:='SELECT bill_id,bill_typeid,bill_sign,start_no,end_no, all_num,bill_time FROM bill_tj_out WHERE userid=:p_userid order by bill_sign,start_no,end_no';

strSql2:='SELECT bill_id,bill_typeid,bill_sign,start_no,end_no, all_num,bill_time FROM bill_tj_out_a WHERE userid='||p_userid
||' order by bill_sign,start_no';

delete bill_tj_out_a where userid=p_userid;
commit;
CUR_1 := dbms_sql.open_cursor; --打开游标;
dbms_sql.parse(CUR_1, strSql1, dbms_sql.native); --解析动态SQL语句;
dbms_sql.bind_variable(CUR_1, ':p_userid', p_userid); --绑定输入参数;

dbms_sql.define_column(CUR_1, 1, t_bill_id_1); --定义列
dbms_sql.define_column(CUR_1, 2, t_bill_typeid_1);
dbms_sql.define_column(CUR_1,3,t_bill_sign_1,12);--字符的应该指定长度,否则会出现错误:PLS-00307: 有太多的 'DEFINE_COLUMN' 说明与此次调用相匹配
dbms_sql.define_column(CUR_1,4, t_start_no_1);
dbms_sql.define_column(CUR_1, 5, t_end_no_1);
dbms_sql.define_column(CUR_1, 6, t_all_num_1);
dbms_sql.define_column(CUR_1, 7, t_bill_time_1);
Cur_1_return:=dbms_sql.execute(CUR_1); --执行动态SQL语句。对于非查询的语句,execute将执行该语句并返回处理了的行的个数。对于查询,execute将确定活动集,返回0
LOOP
EXIT WHEN dbms_sql.fetch_rows(CUR_1)<=0; --fetch_rows在结果集中移动游标,如果未抵达末尾,返回1
dbms_sql.column_value(CUR_1, 1, t_bill_id_1); ----将当前行的查询结果写入上面定义的列中。
dbms_sql.column_value(CUR_1, 2, t_bill_typeid_1);
dbms_sql.column_value(CUR_1,3,t_bill_sign_1);
dbms_sql.column_value(CUR_1,4, t_start_no_1);
dbms_sql.column_value(CUR_1, 5, t_end_no_1);
dbms_sql.column_value(CUR_1, 6, t_all_num_1);
dbms_sql.column_value(CUR_1, 7, t_bill_time_1);

select to_char(t_bill_time_1,'yyyy') into t_bill_time_1_yyyy from dual;--提取日期中的年
select to_char(t_bill_time_1,'mm') into t_bill_time_1_mm from dual;--提取日期中的月
--下面开始打开CUR_2的操作

CUR_2 := dbms_sql.open_cursor; --打开游标;
dbms_sql.parse(CUR_2, strSql2, dbms_sql.native); --解析动态SQL语句;
dbms_sql.bind_variable(CUR_2, ':p_userid', p_userid); --绑定输入参数;

dbms_sql.define_column(CUR_2, 1, t_bill_id_2); --定义列
dbms_sql.define_column(CUR_2, 2, t_bill_typeid_2);
dbms_sql.define_column(CUR_2,3,t_bill_sign_2,12);--字符的应该指定长度,否则会出现错误:PLS-00307: 有太多的 'DEFINE_COLUMN' 说明与此次调用相匹配
dbms_sql.define_column(CUR_2,4, t_start_no_2);
dbms_sql.define_column(CUR_2, 5, t_end_no_2);
dbms_sql.define_column(CUR_2, 6, t_all_num_2);
dbms_sql.define_column(CUR_2, 7, t_bill_time_2);
Cur_1_return:=dbms_sql.execute(CUR_2); --执行动态SQL语句。对于非查询的语句,execute将执行该语句并返回处理了的行的个数。对于查询,execute将确定活动集,返回0
LOOP
EXIT WHEN dbms_sql.fetch_rows(CUR_2)<=0; --fetch_rows在结果集中移动游标,如果未抵达末尾,返回1
dbms_sql.column_value(CUR_2, 1, t_bill_id_2); ----将当前行的查询结果写入上面定义的列中。
dbms_sql.column_value(CUR_2, 2, t_bill_typeid_2);
dbms_sql.column_value(CUR_2,3,t_bill_sign_2);
dbms_sql.column_value(CUR_2,4, t_start_no_2);
dbms_sql.column_value(CUR_2, 5, t_end_no_2);
dbms_sql.column_value(CUR_2, 6, t_all_num_2);
dbms_sql.column_value(CUR_2, 7, t_bill_time_2);

select to_char(t_bill_time_2,'yyyy') into t_bill_time_2_yyyy from dual;--提取日期中的年
select to_char(t_bill_time_2,'mm') into t_bill_time_2_mm from dual;--提取日期中的月
if(t_bill_sign_1=t_bill_sign_2 and t_bill_typeid_1=t_bill_typeid_2 and t_bill_time_1_yyyy=t_bill_time_2_yyyy
and t_bill_time_1_mm=t_bill_time_2_mm and (t_end_no_2+1=t_start_no_1)) then
t_bill_id_2_merge:=t_bill_id_1;

end if;

END LOOP;
dbms_sql.close_cursor(CUR_2); --关闭游标。
--判断是否可以合并。不可以合并则插入到bill_tj_out_a中
if t_bill_id_2_merge<>0 then

update bill_tj_out_a set bill_tj_out_a.bill_id=t_bill_id_1,end_no=t_end_no_1,bill_time=t_bill_time_1,all_num=all_num+t_all_num_1
where bill_id=t_bill_id_2 and userid=p_userid;
delete bill_tj_out where bill_id=t_bill_id_2_merge and userid=p_userid;
commit;
t_bill_id_2_merge:=0;
else
insert into bill_tj_out_a select * from bill_tj_out where userid=p_userid and bill_id=t_bill_id_1;
delete bill_tj_out where bill_id=t_bill_id_1 and userid=p_userid;

commit;
end if;
--t_bill_id_2_merge:=0;*/
dbms_sql.close_cursor(CUR_1); --关闭游标。
-- 再重新打开游标;
CUR_1 := dbms_sql.open_cursor; --打开游标;
dbms_sql.parse(CUR_1, strSql1, dbms_sql.native); --解析动态SQL语句;
dbms_sql.bind_variable(CUR_1, ':p_userid', p_userid); --绑定输入参数;

dbms_sql.define_column(CUR_1, 1, t_bill_id_1); --定义列
dbms_sql.define_column(CUR_1, 2, t_bill_typeid_1);
dbms_sql.define_column(CUR_1,3,t_bill_sign_1,12);--字符的应该指定长度,否则会出现错误:PLS-00307: 有太多的 'DEFINE_COLUMN' 说明与此次调用相匹配
dbms_sql.define_column(CUR_1,4, t_start_no_1);
dbms_sql.define_column(CUR_1, 5, t_end_no_1);
dbms_sql.define_column(CUR_1, 6, t_all_num_1);
dbms_sql.define_column(CUR_1, 7, t_bill_time_1);
Cur_1_return:=dbms_sql.execute(CUR_1);

END LOOP;commit;
---下面重新计算结存数量

end Pro_Remain_Merge_Win_1;

--看来在Oracle817下的存储过程简单多了,据说在8.05以前都不支持OPen Cursor的写法,

这两个存储过程分别在Oracle817和Oracle7.3.4下测试正确。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: