请大神写一个详细示例。要不然我看不懂,急急急
急。有没有 oracle前辈 花点时间,有偿有偿指导一下我。
请教一个存储过程问题
场景模拟:
我要插入一批数据
A
B
C
DDD
进入目标表,目标表只有一个字段CHAR(2)
现在有四条数据要插入进去,其中一条字符长度超长了。正常insert会存储过程报错,四条都插不进去,我想继续执行把其他三条正常插入到目标表,报错那一条记录的到日志
--创建测试数据表
create table T_INSERT_DATA
(
val VARCHAR2(100)
);
--插入测试数据
insert into t_insert_data values('A');
insert into t_insert_data values('B');
insert into t_insert_data values('C');
insert into t_insert_data values('DDD');
--创建需要插入数据的目标表
create table T_INSERT
(
val VARCHAR2(1)
);
--创建问题数据日志表
create table T_INSERT_LOG
(
val VARCHAR2(100)
);
--测试的PLSQL脚本
declare
v_val varchar2(100);
begin
for i in (select td.val from T_INSERT_DATA td) loop
v_val := i.val;
insert into t_insert (val) values (v_val);
end loop;
commit;
exception
when others then
insert into t_insert_log (val) values (v_val);
commit;
end;
create table tab(dat char(2));
BEGIN
dbms_errlog.create_error_log(dml_table_name => 'tab');
END;
insert into tab(dat)
select 'a' from dual
union all
select 'ab' from dual
union all
select 'abc' from dual
LOG ERRORS INTO err$_tab ('INSERT') REJECT LIMIT UNLIMITED;
select * from tab
select * from err$_tab
--建个临时表(目标表)CREATE TABLE TEMP_0827 (TEST CHAR(2))
-- Create table
/*日志表自己平时用的,结构勉强够看
create table PRO_LOG
(
procedure_name VARCHAR2(100),
starttime DATE,
endtime DATE,
status VARCHAR2(10) not null,
message VARCHAR2(200),
procedure_id VARCHAR2(20),
sqlcount NUMBER
)
tablespace GCIBISP
pctfree 10
initrans 1
maxtrans 255
storage
(
initial 16K
next 8K
minextents 1
maxextents unlimited
);
-- Add comments to the columns
comment on column PRO_LOG.procedure_name
is '存储名称';
comment on column PRO_LOG.starttime
is '开始时间';
comment on column PRO_LOG.endtime
is '结束时间';
comment on column PRO_LOG.status
is '状态 1开始,2结束,3异常';
comment on column PRO_LOG.message
is '详细日志,异常信息';
comment on column PRO_LOG.procedure_id
is '存储id';
comment on column PRO_LOG.sqlcount
is '数据变化量';
*/
CREATE OR REPLACE PROCEDURE TEMP_TEST AS
REC VARCHAR2(10);
ERRORCODE VARCHAR2(10);
ERRORMSG VARCHAR2(200); --异常信息
--SQLCOUNT NUMBER;--变化条数
-- E NUMBER;
CURSOR TEMP_CURSOR IS
SELECT 'A'
FROM DUAL
UNION ALL
SELECT 'B'
FROM DUAL
UNION ALL
SELECT 'C'
FROM DUAL
UNION ALL
SELECT 'DDD'
FROM DUAL;
BEGIN
EXECUTE IMMEDIATE 'TRUNCATE TABLE TEMP_0827';
OPEN TEMP_CURSOR;
LOOP
FETCH TEMP_CURSOR
INTO REC;
INSERT INTO TEMP_0827
(TEST)
SELECT REC FROM DUAL;
COMMIT;
EXIT WHEN TEMP_CURSOR%NOTFOUND;
END LOOP;
CLOSE TEMP_CURSOR;
--更新日志表,内容:更新存储过程中异常信息
EXCEPTION
WHEN OTHERS THEN
ERRORCODE := SQLCODE;
ERRORMSG := SUBSTR(SQLERRM, 1, 200);
DBMS_OUTPUT.PUT_LINE(SQLCODE || '----' || ERRORMSG);
INSERT INTO PRO_LOG
(STATUS, MESSAGE, ENDTIME, PROCEDURE_NAME)
SELECT '3', ERRORCODE || '----' || ERRORMSG, SYSDATE, 'TEMP_TEST'
FROM DUAL;
COMMIT;
END TEMP_TEST;
--创建测试数据表
create table INSERT_TAB
(
val VARCHAR2(50)
);
--插入测试数据
insert into INSERT_TAB values('A');
insert into INSERT_TAB values('B');
insert into INSERT_TAB values('C');
insert into INSERT_TAB values('DDD');
--创建需要插入数据的目标表
create table T_INSERT
(
val VARCHAR2(2)
);
--创建问题数据日志表
create table T_INSERT_LOG
(
val VARCHAR2(100)
);
--创建存储过程
create or replace procedure Insert_procedure AS
--创建游标,查询出字段内容以及字段长度
Cursor insert_cursor is
select tab.val ,length(tab.val) as "len" from INSERT_TAB tab;
--定义游标类型
cur insert_cursor%rowtype;
--便利游标
BEGIN
for cur in insert_cursor loop
--如果长度大于2 插入日志表
if cur.len > 2 then
insert into T_INSERT_LOG (val) values (cur.val);
else
--如果长度不大于2插入数据表
insert into T_INSERT (val) values (cur.val);
end if;
end loop;
commit;
end;
declare
begin
for .. loop
begin
insert into ....
end
exception
insert into log
end loop
end;
/