如何解决从阵列插入数据时Oracle下标超出计数错误?
我开发了如下存储过程:如何解决从阵列插入数据时Oracle下标超出计数错误?,oracle,stored-procedures,plsql,oracle12c,Oracle,Stored Procedures,Plsql,Oracle12c,我开发了如下存储过程: create or replace PROCEDURE PROC_INS ( GB_LD_ID IN NUMBER, GB_CS_SP IN TBL_CHAR, GB_UF_NMS IN TBL_CHAR, GB_RW_BRS IN TBL_NBR, GB_RT_SMS
create or replace
PROCEDURE PROC_INS (
GB_LD_ID IN NUMBER,
GB_CS_SP IN TBL_CHAR,
GB_UF_NMS IN TBL_CHAR,
GB_RW_BRS IN TBL_NBR,
GB_RT_SMS IN TBL_CHAR,
GB_LC_SD IN TBL_CHAR)
AS
LV_ERROR NUMBER(10);
LV_MESSAGE varchar2(512);
LV_TM_DI NUMBER(19);
BEGIN
select max(ID) into LV_TM_DI from TME_TAB;
if(LV_TM_DI IS NULL)THEN
LV_TM_DI:=0;
end if;
FOR i IN GB_RW_BRS.FIRST..GB_RW_BRS.LAST
LOOP
BEGIN
Insert into TME_TAB (ID,VS,PUCS,DT_CRD,NGL_ID,NAME,UD_DT,RW_NHG,TRF_SM,LS_FD)
Values((LV_TM_DI+1),0,GB_CS_SP(i),SYSTIMESTAMP,GB_LD_ID,GB_UF_NMS(i),SYSTIMESTAMP,GB_RW_BRS(i),GB_RT_SMS(i),GB_LC_SD(i));
END;
LV_TM_DI := LV_TM_DI + 1;
END LOOP;
COMMIT;
EXCEPTION
WHEN OTHERS THEN
IF(LV_MESSAGE IS NULL) THEN
LV_ERROR :=-20004;
LV_MESSAGE :=SQLERRM;
END IF;
RAISE_APPLICATION_ERROR (LV_ERROR,LV_MESSAGE);
END PROC_INS;
此过程通过读取类型为TBL\u CHAR
和TBL\u NBR
的数组来插入记录。
TBL_CHAR
定义如下:
create or replace TYPE "TBL_CHAR" AS TABLE OF VARCHAR2(100);
但是当插入运行时,我得到了这个错误:ORA-20004:ORA-06533:Subscript beyond count
有人能帮我吗 看起来数组的元素数不同。我的测试:
create or replace type tbl_char as table of varchar2(100);
create or replace type tbl_nbr as table of number;
create table tme_tab(id number(3), nbr number(5), chr varchar2(100));
create or replace procedure proc_ins ( i_id in number, i_nbr in tbl_nbr, i_chr in tbl_char ) as
lv_tm_di number(6);
begin
select nvl(max(ID), 0) into lv_tm_di from tme_tab;
for i in i_nbr.first..i_nbr.last loop
lv_tm_di := lv_tm_di + 1;
begin
insert into tme_tab (id, nbr, chr) values(lv_tm_di, i_nbr(i), i_chr(i));
end;
end loop;
end proc_ins;
。。。这是有效的:
begin
proc_ins(1, tbl_nbr(1, 7, 0), tbl_char('P', 'Q', 'R'));
end;
。。。这不起作用(ORA-06533):
插入前检查大小并引发异常:
if i_nbr.count <> i_chr.count then
raise_application_error (-20001, 'wrong array dimmensions');
end if;
如果i_nbr.count i_chr.count那么
引发应用程序错误(-20001,“错误的阵列调光”);
如果结束;
或者为较短的数组插入空值。此外,您的过程在生成ID时使用计数器,而考虑使用序列,对于并发更新非常重要。UL>
序列
获取唯一ID(而不是MAX
)CREATE TABLE TME_TAB (
ID int,
VS int,
PUCS char(100),
DT_CRD timestamp,
NGL_ID number,
NAME char(100),
UD_DT timestamp,
RW_NHG number,
TRF_SM char(100),
LS_FD char(100)
)
/
CREATE TYPE TBL_CHAR IS TABLE OF CHAR(100)
/
CREATE TYPE TBL_NBR IS TABLE OF NUMBER
/
CREATE SEQUENCE TME_TAB__ID__SEQ
/
create or replace PROCEDURE PROC_INS (
GB_LD_ID IN NUMBER,
GB_CS_SP IN TBL_CHAR,
GB_UF_NMS IN TBL_CHAR,
GB_RW_BRS IN TBL_NBR,
GB_RT_SMS IN TBL_CHAR,
GB_LC_SD IN TBL_CHAR)
AS
LV_ERROR NUMBER(10);
LV_MESSAGE varchar2(512);
LV_TM_DI NUMBER(19);
BEGIN
FOR i IN 1 .. LEAST(
GB_CS_SP.COUNT,
GB_UF_NMS.COUNT,
GB_RW_BRS.COUNT,
GB_RT_SMS.COUNT,
GB_LC_SD.COUNT
)
LOOP
Insert into TME_TAB (
ID, VS, PUCS, DT_CRD,
NGL_ID, NAME, UD_DT, RW_NHG,
TRF_SM, LS_FD
) Values(
TME_TAB__ID__SEQ.NEXTVAL, 0, GB_CS_SP(i), SYSTIMESTAMP,
GB_LD_ID, GB_UF_NMS(i), SYSTIMESTAMP, GB_RW_BRS(i),
GB_RT_SMS(i), GB_LC_SD(i)
);
END LOOP;
EXCEPTION
WHEN OTHERS THEN
IF(LV_MESSAGE IS NULL) THEN
LV_ERROR :=-20004;
LV_MESSAGE :=SQLERRM;
END IF;
RAISE_APPLICATION_ERROR (LV_ERROR,LV_MESSAGE);
END PROC_INS;
/
BEGIN
PROC_INS (
GB_LD_ID => 1,
GB_CS_SP => TBL_CHAR( 'sp_a', 'sp_b' ),
GB_UF_NMS => TBL_CHAR( 'nms_a', 'nms_b' ),
GB_RW_BRS => TBL_NBR( 1.1, 1.2 ),
GB_RT_SMS => TBL_CHAR( 'sms_a', 'sms_b' ),
GB_LC_SD => TBL_CHAR( 'sd_a', 'sd_b' )
);
COMMIT;
END;
SELECT * FROM TME_TAB
| ID | VS | PUCS | DT_CRD | NGL_ID | NAME | UD_DT | RW_NHG | TRF_SM | LS_FD |
|----|----|------------------------------------------------------------------------------------------------------|----------------------------|--------|------------------------------------------------------------------------------------------------------|----------------------------|--------|------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------|
| 1 | 0 | sp_a | 2018-07-18 11:07:31.827742 | 1 | nms_a | 2018-07-18 11:07:31.827742 | 1.1 | sms_a | sd_a |
| 2 | 0 | sp_b | 2018-07-18 11:07:31.828545 | 1 | nms_b | 2018-07-18 11:07:31.828545 | 1.2 | sms_b | sd_b |
查询1:
CREATE TABLE TME_TAB (
ID int,
VS int,
PUCS char(100),
DT_CRD timestamp,
NGL_ID number,
NAME char(100),
UD_DT timestamp,
RW_NHG number,
TRF_SM char(100),
LS_FD char(100)
)
/
CREATE TYPE TBL_CHAR IS TABLE OF CHAR(100)
/
CREATE TYPE TBL_NBR IS TABLE OF NUMBER
/
CREATE SEQUENCE TME_TAB__ID__SEQ
/
create or replace PROCEDURE PROC_INS (
GB_LD_ID IN NUMBER,
GB_CS_SP IN TBL_CHAR,
GB_UF_NMS IN TBL_CHAR,
GB_RW_BRS IN TBL_NBR,
GB_RT_SMS IN TBL_CHAR,
GB_LC_SD IN TBL_CHAR)
AS
LV_ERROR NUMBER(10);
LV_MESSAGE varchar2(512);
LV_TM_DI NUMBER(19);
BEGIN
FOR i IN 1 .. LEAST(
GB_CS_SP.COUNT,
GB_UF_NMS.COUNT,
GB_RW_BRS.COUNT,
GB_RT_SMS.COUNT,
GB_LC_SD.COUNT
)
LOOP
Insert into TME_TAB (
ID, VS, PUCS, DT_CRD,
NGL_ID, NAME, UD_DT, RW_NHG,
TRF_SM, LS_FD
) Values(
TME_TAB__ID__SEQ.NEXTVAL, 0, GB_CS_SP(i), SYSTIMESTAMP,
GB_LD_ID, GB_UF_NMS(i), SYSTIMESTAMP, GB_RW_BRS(i),
GB_RT_SMS(i), GB_LC_SD(i)
);
END LOOP;
EXCEPTION
WHEN OTHERS THEN
IF(LV_MESSAGE IS NULL) THEN
LV_ERROR :=-20004;
LV_MESSAGE :=SQLERRM;
END IF;
RAISE_APPLICATION_ERROR (LV_ERROR,LV_MESSAGE);
END PROC_INS;
/
BEGIN
PROC_INS (
GB_LD_ID => 1,
GB_CS_SP => TBL_CHAR( 'sp_a', 'sp_b' ),
GB_UF_NMS => TBL_CHAR( 'nms_a', 'nms_b' ),
GB_RW_BRS => TBL_NBR( 1.1, 1.2 ),
GB_RT_SMS => TBL_CHAR( 'sms_a', 'sms_b' ),
GB_LC_SD => TBL_CHAR( 'sd_a', 'sd_b' )
);
COMMIT;
END;
SELECT * FROM TME_TAB
| ID | VS | PUCS | DT_CRD | NGL_ID | NAME | UD_DT | RW_NHG | TRF_SM | LS_FD |
|----|----|------------------------------------------------------------------------------------------------------|----------------------------|--------|------------------------------------------------------------------------------------------------------|----------------------------|--------|------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------|
| 1 | 0 | sp_a | 2018-07-18 11:07:31.827742 | 1 | nms_a | 2018-07-18 11:07:31.827742 | 1.1 | sms_a | sd_a |
| 2 | 0 | sp_b | 2018-07-18 11:07:31.828545 | 1 | nms_b | 2018-07-18 11:07:31.828545 | 1.2 | sms_b | sd_b |
:
CREATE TABLE TME_TAB (
ID int,
VS int,
PUCS char(100),
DT_CRD timestamp,
NGL_ID number,
NAME char(100),
UD_DT timestamp,
RW_NHG number,
TRF_SM char(100),
LS_FD char(100)
)
/
CREATE TYPE TBL_CHAR IS TABLE OF CHAR(100)
/
CREATE TYPE TBL_NBR IS TABLE OF NUMBER
/
CREATE SEQUENCE TME_TAB__ID__SEQ
/
create or replace PROCEDURE PROC_INS (
GB_LD_ID IN NUMBER,
GB_CS_SP IN TBL_CHAR,
GB_UF_NMS IN TBL_CHAR,
GB_RW_BRS IN TBL_NBR,
GB_RT_SMS IN TBL_CHAR,
GB_LC_SD IN TBL_CHAR)
AS
LV_ERROR NUMBER(10);
LV_MESSAGE varchar2(512);
LV_TM_DI NUMBER(19);
BEGIN
FOR i IN 1 .. LEAST(
GB_CS_SP.COUNT,
GB_UF_NMS.COUNT,
GB_RW_BRS.COUNT,
GB_RT_SMS.COUNT,
GB_LC_SD.COUNT
)
LOOP
Insert into TME_TAB (
ID, VS, PUCS, DT_CRD,
NGL_ID, NAME, UD_DT, RW_NHG,
TRF_SM, LS_FD
) Values(
TME_TAB__ID__SEQ.NEXTVAL, 0, GB_CS_SP(i), SYSTIMESTAMP,
GB_LD_ID, GB_UF_NMS(i), SYSTIMESTAMP, GB_RW_BRS(i),
GB_RT_SMS(i), GB_LC_SD(i)
);
END LOOP;
EXCEPTION
WHEN OTHERS THEN
IF(LV_MESSAGE IS NULL) THEN
LV_ERROR :=-20004;
LV_MESSAGE :=SQLERRM;
END IF;
RAISE_APPLICATION_ERROR (LV_ERROR,LV_MESSAGE);
END PROC_INS;
/
BEGIN
PROC_INS (
GB_LD_ID => 1,
GB_CS_SP => TBL_CHAR( 'sp_a', 'sp_b' ),
GB_UF_NMS => TBL_CHAR( 'nms_a', 'nms_b' ),
GB_RW_BRS => TBL_NBR( 1.1, 1.2 ),
GB_RT_SMS => TBL_CHAR( 'sms_a', 'sms_b' ),
GB_LC_SD => TBL_CHAR( 'sd_a', 'sd_b' )
);
COMMIT;
END;
SELECT * FROM TME_TAB
| ID | VS | PUCS | DT_CRD | NGL_ID | NAME | UD_DT | RW_NHG | TRF_SM | LS_FD |
|----|----|------------------------------------------------------------------------------------------------------|----------------------------|--------|------------------------------------------------------------------------------------------------------|----------------------------|--------|------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------|
| 1 | 0 | sp_a | 2018-07-18 11:07:31.827742 | 1 | nms_a | 2018-07-18 11:07:31.827742 | 1.1 | sms_a | sd_a |
| 2 | 0 | sp_b | 2018-07-18 11:07:31.828545 | 1 | nms_b | 2018-07-18 11:07:31.828545 | 1.2 | sms_b | sd_b |
查询2:
CREATE TABLE TME_TAB (
ID int,
VS int,
PUCS char(100),
DT_CRD timestamp,
NGL_ID number,
NAME char(100),
UD_DT timestamp,
RW_NHG number,
TRF_SM char(100),
LS_FD char(100)
)
/
CREATE TYPE TBL_CHAR IS TABLE OF CHAR(100)
/
CREATE TYPE TBL_NBR IS TABLE OF NUMBER
/
CREATE SEQUENCE TME_TAB__ID__SEQ
/
create or replace PROCEDURE PROC_INS (
GB_LD_ID IN NUMBER,
GB_CS_SP IN TBL_CHAR,
GB_UF_NMS IN TBL_CHAR,
GB_RW_BRS IN TBL_NBR,
GB_RT_SMS IN TBL_CHAR,
GB_LC_SD IN TBL_CHAR)
AS
LV_ERROR NUMBER(10);
LV_MESSAGE varchar2(512);
LV_TM_DI NUMBER(19);
BEGIN
FOR i IN 1 .. LEAST(
GB_CS_SP.COUNT,
GB_UF_NMS.COUNT,
GB_RW_BRS.COUNT,
GB_RT_SMS.COUNT,
GB_LC_SD.COUNT
)
LOOP
Insert into TME_TAB (
ID, VS, PUCS, DT_CRD,
NGL_ID, NAME, UD_DT, RW_NHG,
TRF_SM, LS_FD
) Values(
TME_TAB__ID__SEQ.NEXTVAL, 0, GB_CS_SP(i), SYSTIMESTAMP,
GB_LD_ID, GB_UF_NMS(i), SYSTIMESTAMP, GB_RW_BRS(i),
GB_RT_SMS(i), GB_LC_SD(i)
);
END LOOP;
EXCEPTION
WHEN OTHERS THEN
IF(LV_MESSAGE IS NULL) THEN
LV_ERROR :=-20004;
LV_MESSAGE :=SQLERRM;
END IF;
RAISE_APPLICATION_ERROR (LV_ERROR,LV_MESSAGE);
END PROC_INS;
/
BEGIN
PROC_INS (
GB_LD_ID => 1,
GB_CS_SP => TBL_CHAR( 'sp_a', 'sp_b' ),
GB_UF_NMS => TBL_CHAR( 'nms_a', 'nms_b' ),
GB_RW_BRS => TBL_NBR( 1.1, 1.2 ),
GB_RT_SMS => TBL_CHAR( 'sms_a', 'sms_b' ),
GB_LC_SD => TBL_CHAR( 'sd_a', 'sd_b' )
);
COMMIT;
END;
SELECT * FROM TME_TAB
| ID | VS | PUCS | DT_CRD | NGL_ID | NAME | UD_DT | RW_NHG | TRF_SM | LS_FD |
|----|----|------------------------------------------------------------------------------------------------------|----------------------------|--------|------------------------------------------------------------------------------------------------------|----------------------------|--------|------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------|
| 1 | 0 | sp_a | 2018-07-18 11:07:31.827742 | 1 | nms_a | 2018-07-18 11:07:31.827742 | 1.1 | sms_a | sd_a |
| 2 | 0 | sp_b | 2018-07-18 11:07:31.828545 | 1 | nms_b | 2018-07-18 11:07:31.828545 | 1.2 | sms_b | sd_b |
:
CREATE TABLE TME_TAB (
ID int,
VS int,
PUCS char(100),
DT_CRD timestamp,
NGL_ID number,
NAME char(100),
UD_DT timestamp,
RW_NHG number,
TRF_SM char(100),
LS_FD char(100)
)
/
CREATE TYPE TBL_CHAR IS TABLE OF CHAR(100)
/
CREATE TYPE TBL_NBR IS TABLE OF NUMBER
/
CREATE SEQUENCE TME_TAB__ID__SEQ
/
create or replace PROCEDURE PROC_INS (
GB_LD_ID IN NUMBER,
GB_CS_SP IN TBL_CHAR,
GB_UF_NMS IN TBL_CHAR,
GB_RW_BRS IN TBL_NBR,
GB_RT_SMS IN TBL_CHAR,
GB_LC_SD IN TBL_CHAR)
AS
LV_ERROR NUMBER(10);
LV_MESSAGE varchar2(512);
LV_TM_DI NUMBER(19);
BEGIN
FOR i IN 1 .. LEAST(
GB_CS_SP.COUNT,
GB_UF_NMS.COUNT,
GB_RW_BRS.COUNT,
GB_RT_SMS.COUNT,
GB_LC_SD.COUNT
)
LOOP
Insert into TME_TAB (
ID, VS, PUCS, DT_CRD,
NGL_ID, NAME, UD_DT, RW_NHG,
TRF_SM, LS_FD
) Values(
TME_TAB__ID__SEQ.NEXTVAL, 0, GB_CS_SP(i), SYSTIMESTAMP,
GB_LD_ID, GB_UF_NMS(i), SYSTIMESTAMP, GB_RW_BRS(i),
GB_RT_SMS(i), GB_LC_SD(i)
);
END LOOP;
EXCEPTION
WHEN OTHERS THEN
IF(LV_MESSAGE IS NULL) THEN
LV_ERROR :=-20004;
LV_MESSAGE :=SQLERRM;
END IF;
RAISE_APPLICATION_ERROR (LV_ERROR,LV_MESSAGE);
END PROC_INS;
/
BEGIN
PROC_INS (
GB_LD_ID => 1,
GB_CS_SP => TBL_CHAR( 'sp_a', 'sp_b' ),
GB_UF_NMS => TBL_CHAR( 'nms_a', 'nms_b' ),
GB_RW_BRS => TBL_NBR( 1.1, 1.2 ),
GB_RT_SMS => TBL_CHAR( 'sms_a', 'sms_b' ),
GB_LC_SD => TBL_CHAR( 'sd_a', 'sd_b' )
);
COMMIT;
END;
SELECT * FROM TME_TAB
| ID | VS | PUCS | DT_CRD | NGL_ID | NAME | UD_DT | RW_NHG | TRF_SM | LS_FD |
|----|----|------------------------------------------------------------------------------------------------------|----------------------------|--------|------------------------------------------------------------------------------------------------------|----------------------------|--------|------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------|
| 1 | 0 | sp_a | 2018-07-18 11:07:31.827742 | 1 | nms_a | 2018-07-18 11:07:31.827742 | 1.1 | sms_a | sd_a |
| 2 | 0 | sp_b | 2018-07-18 11:07:31.828545 | 1 | nms_b | 2018-07-18 11:07:31.828545 | 1.2 | sms_b | sd_b |
所有这些TBL_字符、TBL_NBR、TBL_字符数组大小相同吗?假设GB_RW_BRS大小为10,但GB_CS_SP为7,则当您在GB_RW中处理8条记录时,可能会引发类似的错误_BRS@Gaj . 它们的大小将相同。如果可能,请使用extend,然后尝试插入您对过程的示例调用(导致此错误的调用)