我正在执行PL / SQL代码以显示失败预订表中的货币代码。使用对象类型和嵌套表集合。
运行PL / SQL代码时,会生成以下错误。相应的行在PL / SQL代码部分中突出显示。
错误报告:
ORA-06550: line 27, column 11:
PL/SQL: ORA-00932: inconsistent datatypes: expected UDT got NUMBER
ORA-06550: line 27, column 4:
PL/SQL: SQL Statement ignored
06550. 00000 - "line %s, column %s:\n%s"
*Cause: Usually a PL/SQL compilation error.
*Action:
代码粘贴在下面:
DDL - 创建表格
CREATE TABLE FAILEDRESERVATION
(
FAILEDRESERVATIONID NUMBER(18,0),
FK_TRANSACTIONID NUMBER(18,0),
DEBITRESERVATIONID NUMBER(18,0),
RESERVATIONTIME DATE,
RESERVATIONAMOUNT NUMBER(18,5),
CURRENCYCODE CHAR(3 BYTE),
AVAILABLEAMOUNT NUMBER(18,5)
);
ALTER TABLE FAILEDRESERVATION
ADD CONSTRAINT "PK_FAILEDRESERVATION" PRIMARY KEY ("FAILEDRESERVATIONID");
对象类型:
CREATE OR REPLACE TYPE TYPE type_failedreservation AS OBJECT
(
FK_TRANSACTIONID NUMBER(18),
DEBITRESERVATIONID NUMBER(18),
RESERVATIONTIME DATE,
RESERVATIONAMOUNT NUMBER(18,5),
CURRENCYCODE CHAR(3),
AVAILABLEAMOUNT NUMBER(18,5)
);
DML:
INSERT INTO FAILEDRESERVATION (FAILEDRESERVATIONID,FK_TRANSACTIONID,DEBITRESERVATIONID,RESERVATIONTIME,RESERVATIONAMOUNT,CURRENCYCODE,AVAILABLEAMOUNT)
VALUES (289,2,1,to_date('07-MAR-16','DD-MON-RR'),20000,'USD',10000);
INSERT INTO FAILEDRESERVATION (FAILEDRESERVATIONID,FK_TRANSACTIONID,DEBITRESERVATIONID,RESERVATIONTIME,RESERVATIONAMOUNT,CURRENCYCODE,AVAILABLEAMOUNT)
VALUES (288,1,1,to_date('01-MAR-16','DD-MON-RR'),10000,'NOK',10000);
嵌套表:
CREATE OR REPLACE TYPE type_failedreservation_coll as TABLE OF type_failedreservation;
CREATE OR REPLACE TYPE type_dbtrsid_coll AS TABLE OF NUMBER;
PL / SQL代码:
DECLARE
P_FAILEDRESERVATION APPDATA.TYPE_FAILEDRESERVATION_COLL;
vdbtid_coll type_dbtrsid_coll := type_dbtrsid_coll();
BEGIN
SELECT TYPE_FAILEDRESERVATION(fk_transactionid,debitreservationid,reservationtime,reservationamount,currencycode,availableamount)
BULK COLLECT
INTO p_failedreservation
FROM failedreservation;
-- This is line 27
SELECT frs.debitreservationid
INTO vdbtid_coll
FROM TABLE(p_failedreservation) frs;
FOR v_iterate IN vdbtid_coll.FIRST..vdbtid_coll.LAST
LOOP
dbms_output.put_line('The currency code is: '||v_iterate);
END LOOP;
END;
为什么代码会产生此错误?
答案 0 :(得分:4)
您已将vdbtid_coll
声明为收集类型,因此您还需要批量收集:
SELECT frs.debitreservationid
BULK COLLECT INTO vdbtid_coll
FROM TABLE(p_failedreservation) frs;
随着这一变化:
PL/SQL procedure successfully completed.
The currency code is: 1
The currency code is: 2
虽然这只是给你收藏中的索引编号,所以我不认为这是你真正想要的。你可能想要:
FOR v_iterate IN vdbtid_coll.FIRST..vdbtid_coll.LAST
LOOP
dbms_output.put_line('The currency code is: '
|| p_failedreservation(v_iterate).currencycode);
END LOOP;
得到:
PL/SQL procedure successfully completed.
The currency code is: USD
The currency code is: NOK
你根本不需要第二个选择/收藏,你可以这样做:
FOR v_iterate IN 1..p_failedreservation.COUNT
LOOP
dbms_output.put_line('The currency code is: '
|| p_failedreservation(v_iterate).currencycode);
END LOOP;
...得到相同的结果。虽然我不确定debitreservationid
在第二个查询中的相关性,因为它在两行中都是相同的值(1)。
答案 1 :(得分:2)
您正尝试在集合中选择多行。您需要使用BULK COLLECT INTO
而不仅仅是INTO
。
更改
SELECT frs.debitreservationid
INTO vdbtid_coll
FROM TABLE(p_failedreservation) frs;
要
SELECT frs.debitreservationid
BULK COLLECT INTO vdbtid_coll
FROM TABLE(p_failedreservation) frs;
你可能希望输出为:
FOR v_iterate IN vdbtid_coll.FIRST..vdbtid_coll.LAST LOOP
dbms_output.put_line('The currency code is: '|| vdbtid_coll(v_iterate) );
END LOOP;
但是,您可以将其全部简化为:
DECLARE
P_FAILEDRESERVATION APPDATA.TYPE_FAILEDRESERVATION_COLL;
BEGIN
SELECT TYPE_FAILEDRESERVATION(
fk_transactionid,
debitreservationid,
reservationtime,
reservationamount,
currencycode,
availableamount
)
BULK COLLECT INTO p_failedreservation
FROM failedreservation;
FOR v_iterate IN p_failedreservation.FIRST .. p_failedreservation.LAST LOOP
dbms_output.put_line(
'The currency code is: '|| p_failedreservation(v_iterate).currencycode
);
END LOOP;
END;
答案 2 :(得分:1)
尝试将类型数组转换为其类型,如下所示
SELECT frs.debitreservationid
BULK COLLECT INTO vdbtid_coll
FROM TABLE(CAST(p_failedreservation as APPDATA.TYPE_FAILEDRESERVATION_COLL)) frs;
答案 3 :(得分:0)
PL / SQL:ORA-00932:数据类型不一致:预期的UDT得到了CHAR
如果在以下情况下写类型表代替类型对象,则可能会出现此错误: 使用批量收集进入,我遇到了这个错误,因为我这样做了。
例如:
CREATE OR REPLACE TYPE OBJ_TYPE AS OBJECT (NAME VARCHAR2(20));
/
CREATE OR REPLACE TYPE TBL_TYPE IS TABLE OF OBJ_TYPE;
/
CREATE OR REPLACE FUNCTION FUNC1 RETURN TBL_TYPE AS
TBL_TEXT TBL_TYPE := TBL_TYPE();
BEGIN
SELECT ***OBJ_TYPE*** (NAME) BULK COLLECT INTO ***TBL_TEXT*** FROM <table-name> ;
RETURN ***TBL_TEXT***;
END;
/
在函数中使用对象类型和表类型时应格外小心。