-- 第一个题目,我的表叫stu,你别忘了改成你的表名
创新互联网络公司拥有10余年的成都网站开发建设经验,成百上千客户的共同信赖。提供成都做网站、网站制作、网站开发、网站定制、友情链接、建网站、网站搭建、成都响应式网站建设公司、网页设计师打造企业风格,提供周到的售前咨询和贴心的售后服务
create or replace procedure pro7
as
cursor c_emp1 is select ename,sal from stu;
vename stu.ename%type;
vsal stu.sal%type;
vnewsal stu.sal%type;
vfd number := 0;
begin
open c_emp1;
loop
fetch c_emp1 into vename,vsal;
exit when c_emp1%notfound;
vfd := vsal*0.2;
if vfd = 300
then update stu set sal = sal+vfd where ename=vename;
vnewsal := vsal+vfd;
dbms_output.put_line('员工' || vename || '涨了' || vnewsal || '工资');
end if;
end loop;
close c_emp1;
end;
--打开游标并提取后面SQL的第一行数据放到游标中 这里就是打开游标
open for 是隐式游标的写法 不建议使用 这种游标好象不需要关闭 具体你自己测试下 而且少了expection 处理
fetch mycur into yang_02;
--循环插入数据
多余了 可以不要 前面有fetch了如果还有这里的话 就只能插入奇数行
其他没什么问题了 还有你这个过程用ref cursor是浪费 没必要用 用简单的显示游标更好点
--创建存储
程
CREATE
OR
REPLACE
PROCEDURE
xxxxxxxxxxx_p
(
--参数IN表示输入参数
OUT表示输入参数
类型
使用任意Oracle
合
类型
is_ym
IN
CHAR
)
AS
--定义变量
vs_msg
VARCHAR2(4000);
--错误信息变量
vs_ym_beg
CHAR(6);
--起始月份
vs_ym_end
CHAR(6);
--终止月份
vs_ym_sn_beg
CHAR(6);
--同期起始月份
vs_ym_sn_end
CHAR(6);
--同期终止月份
--定义游标(简单
说
遍历
结
集)
CURSOR
cur_1
IS
SELECT
area_code,CMCODE,SUM(rmb_amt)/10000
rmb_amt_sn,SUM(usd_amt)/10000
usd_amt_sn
FROM
BGD_AREA_CM_M_BASE_T
WHERE
ym
=
vs_ym_sn_beg
AND
ym
=
vs_ym_sn_end
GROUP
BY
area_code,CMCODE;BEGIN
--用输入参数给变量赋初值
用
Oralce
SUBSTR
TO_CHAR
ADD_MONTHS
TO_DATE
等
用
函数
vs_ym_beg
:=
SUBSTR(is_ym,1,6);
vs_ym_end
:=
SUBSTR(is_ym,7,6);
vs_ym_sn_beg
:=
TO_CHAR(ADD_MONTHS(TO_DATE(vs_ym_beg,'yyyymm'),
-12),'yyyymm');
vs_ym_sn_end
:=
TO_CHAR(ADD_MONTHS(TO_DATE(vs_ym_end,'yyyymm'),
-12),'yyyymm');
--先删除表
特定条件
数据
DELETE
FROM
xxxxxxxxxxx_T
WHERE
ym
=
is_ym;
--
用内置
DBMS_OUTPUT
象
put_line
打印
影响
记录行数
其
用
系统变量SQL%rowcount
DBMS_OUTPUT.put_line('del
月记录='||SQL%rowcount||'条');
INSERT
INTO
xxxxxxxxxxx_T(area_code,ym,CMCODE,rmb_amt,usd_amt)
SELECT
area_code,is_ym,CMCODE,SUM(rmb_amt)/10000,SUM(usd_amt)/10000
FROM
BGD_AREA_CM_M_BASE_T
WHERE
ym
=
vs_ym_beg
AND
ym
=
vs_ym_end
GROUP
BY
area_code,CMCODE;
DBMS_OUTPUT.put_line('ins
月记录='||SQL%rowcount||'条');
--遍历游标处理
更新
表
遍历游标
几种
用for语句
其
比较直观
种
FOR
rec
IN
cur_1
LOOP
UPDATE
xxxxxxxxxxx_T
SET
rmb_amt_sn
=
rec.rmb_amt_sn,usd_amt_sn
=
rec.usd_amt_sn
WHERE
area_code
=
rec.area_code
AND
CMCODE
=
rec.CMCODE
AND
ym
=
is_ym;
END
LOOP;
COMMIT;
--错误处理部
OTHERS表示除
声明外
任意错误
SQLERRM
系统内置变量保存
前错误
详细信息
EXCEPTION
WHEN
OTHERS
THEN
vs_msg
:=
'ERROR
IN
xxxxxxxxxxx_p('||is_ym||'):'||SUBSTR(SQLERRM,1,500);
ROLLBACK;
--
前错误记录进
志表
INSERT
INTO
LOG_INFO(proc_name,error_info,op_date)
VALUES('xxxxxxxxxxx_p',vs_msg,SYSDATE);
COMMIT;
RETURN;
END;
一、不带参数的游标for循环
1
首先编写存储过程的整体结构,如下:
create or replace procedure test_proc is
v_date date; --变量定义
begin
select sysdate into v_date from dual;
end test_proc;
2
定义游标:
create or replace procedure test_proc is
v_date date; --定义变量
cursor cur is select * from ldcode; --定义游标
begin
select sysdate into v_date from dual;
end test_proc;
3
编写for循环:
create or replace procedure test_proc is
v_date date; --定义变量
cursor cur is select * from ldcode where rownum10; --定义游标
begin
select sysdate into v_date from dual;
--游标for循环开始
for temp in cur loop --temp为临时变量名,自己任意起
Dbms_Output.put_line(temp.Code); --输出某个字段,使用"变量名.列名"即可。
end loop;
--游标for循环结束
end test_proc;
4
测试运行,点击【DBMS Output】标签页查看结果如下图:
END
二、带参数的游标for循环
1
定义带参数的游标:
cursor cur(v_codetype ldcode.Codetype%TYPE) is
select * from ldcode where codetype = v_codetype; --定义游标
定义游标格式:
cursor 游标名称(变量定义) is 查询语句;
注意:
where条件中的变量名v_codetype要与游标定义cur(v_codetype ldcode.Codetype%TYPE)中的一致。
2
编写for循环部分:
--游标for循环开始
for temp in cur('llmedfeetype') loop
--temp为临时变量名,自己任意起
--cur('llmedfeetype')为"游标名称(传入的变量)"
Dbms_Output.put_line(temp.Code); --输出某个字段,使用"变量名.列名"即可。
end loop;
--游标for循环结束
3
测试运行,点击【DBMS Output
有俩种方法:
一种是声明系统游标,一种是声明自定义游标,然后后面操作一样,参数类型为
in out 或out
(1)声明个人系统游标.(推荐)
create or replace p_temp_procedure
(
cur_arg out sys_refcursor; --方法1
)
begin
open cur_arg for select * from tablename;
end
调用
declare
cur_calling sys_refcursor;
begin
p_temp_procedure(cur_calling); --这样这个游标就有值了
for rec_next in cur_calling loop
....
end loop;
end;
(2)在包头中申明一个游表类型,然后调用者申明一个这个类型的游标变量,传给返回游标的存储过程 ,存储过程out这个结果集,这种方法很麻烦.游标类型不能像索引表一样使用create or replace type方法来创建,所以只能在包中申明,并且需要使用/来执行,后面的存储过程才认这个游标类型.(不推荐,但是建议要知道并且要会这种方式,毕竟它有它存在的道理)
--定义全局变量
create or replace package pkg_package
as
type type_cursor is ref cursor;
type type_record is record
(
test01 varchar2(32),
test02 varchar2(32),
test03 varchar2(32)
);
end;
/
--创建返回游标的存储过程
create or replace procedure p_temp_procedure
(
cur_out_arg out pkg_package.type_cursor
)
is
begin
open cur_out_arg for select * from test;
end;
/
--调用
declare
cur_out_arg pkg_package.type_cursor;
rec_arg pkg_package.type_record;
begin
p_temp_procedure(cur_out_arg);
fetch cur_out_arg into rec_arg;
dbms_output.put_line(rec_arg.test01);
dbms_output.put_line(rec_arg.test02);
dbms_output.put_line(rec_arg.test03);
end;