通过包过程插入带有可变数组列的表时出错

Posted

技术标签:

【中文标题】通过包过程插入带有可变数组列的表时出错【英文标题】:Error when insert into table with a varray column through package procedure 【发布时间】:2018-02-01 12:33:39 【问题描述】:

问题是如何插入 VARRAY- 我有一个程序,我在参数中声明为表数据类型 在过程中,我使用插入语句插入表。 我已经面临插入 VARRAY 的问题 我在包装规范中声明了不同的类型并在正文中使用 BT 错误显示:-错误(61,17):PL/SQL:ORA-00932:不一致的数据类型:预期的数字得到了 SCOTT .SYS_PLSQL_75329_19_1

create or replace PACKAGE BODY CBIS_LOAN_PROD_PACKAGE AS 
    PROCEDURE LOAN_PRODUCT_INSERT_PROCEDURE
 (P_PRODUCT_TITLE LOAN_PROD_TAB.PRODUCT_TITLE%TYPE,
  P_PRODUCT_SUMMERY LOAN_PROD_TAB.PRODUCT_SUMMERY%TYPE,
  P_INTEREST_TYPE LOAN_PROD_TAB.INTEREST_TYPE%TYPE,
   P_INTEREST_RATE LOAN_PROD_TAB.INTEREST_RATE%TYPE,
   P_SECURITY_REQD LOAN_PROD_TAB.SECURITY_REQD%TYPE,
   P_MIN_LOAN_AMT LOAN_PROD_TAB.MIN_LOAN_AMT%TYPE,
   P_MAX_LOAN_AMT LOAN_PROD_TAB.PRODUCT_TITLE%TYPE,
   P_TERM_MIN LOAN_PROD_TAB.TERM_MIN%TYPE,
   P_TERM_MAX LOAN_PROD_TAB.TERM_MAX%TYPE,
   P_REPAYMENT_FREQUENCY LOAN_PROD_TAB.REPAYMENT_FREQUENCY%TYPE,
   P_REPAYMENT_AMT LOAN_PROD_TAB.REPAYMENT_AMT%TYPE,
   P_EARLY_REPAY_ALLOWED LOAN_PROD_TAB.EARLY_REPAY_ALLOWED%TYPE,
   P_MIN_AGE_LIMIT LOAN_PROD_TAB.MIN_AGE_LIMIT%TYPE,
   P_MAX_AGE_LIMIT LOAN_PROD_TAB.MAX_AGE_LIMIT%TYPE,
   V_1 VARCHAR2,
   V_2 VARCHAR2,
   V_3 VARCHAR2,
   V_4 VARCHAR2,
   V_5 VARCHAR2,                                    
   P_PROD_START_DT LOAN_PROD_TAB.PROD_START_DT%TYPE,
   P_PROD_END_DT LOAN_PROD_TAB.PROD_END_DT%TYPE,
   P_PROD_STATUS LOAN_PROD_TAB.PROD_STATUS%TYPE)
  IS  
  V_T RESIDENT_VARRAY:=RESIDENT_VARRAY('V_1','V_2','V_3','V_4','V_5');
BEGIN
  INSERT INTO LOAN_PROD_TAB
(
    PRODUCT_TITLE,
    PRODUCT_SUMMERY,
    INTEREST_TYPE,
    INTEREST_RATE,
    SECURITY_REQD,
    MIN_LOAN_AMT,
    MAX_LOAN_AMT,
   TERM_MIN,
   TERM_MAX,
   REPAYMENT_FREQUENCY,
 REPAYMENT_AMT,
 EARLY_REPAY_ALLOWED,
  MIN_AGE_LIMIT,
 MAX_AGE_LIMIT,
  RESIDENT,
  PROD_START_DT,
   PROD_END_DT,
   PROD_STATUS)
    VALUES(P_PRODUCT_TITLE,
    P_PRODUCT_SUMMERY,
    P_INTEREST_TYPE,
    P_INTEREST_RATE,
    P_SECURITY_REQD,
    P_MIN_LOAN_AMT,
    P_MAX_LOAN_AMT,
     P_TERM_MIN,
    P_TERM_MAX,
    P_REPAYMENT_FREQUENCY,
    P_REPAYMENT_AMT,
    P_EARLY_REPAY_ALLOWED,
    P_MIN_AGE_LIMIT,
    P_MAX_AGE_LIMIT,
    V_T,/*PROBLEM IS HERE-Error(61,17): PL/SQL: ORA-00932: inconsistent 
          datatypes: expected NUMBER got SCOTT.SYS_PLSQL_75329_19_1*/
     P_PROD_START_DT,
     P_PROD_END_DT,
  P_PROD_STATUS
   );
          END LOAN_PRODUCT_INSERT_PROCEDURE; 


               END; 

【问题讨论】:

请查看minimal reproducible example。它将帮助您改进您的问题并获得好的答案 LOAN_PROD_TAB.V_T 列是什么数据类型?是否所有参数 V_1、V_2、V_3、V_4、V_5 都有值? LOAN_PROD_TAB 有一个 DATATYPE 为 RESIDENT_VARRAY(VARRAY DATATYPE :VARRAY(5) OF VARCHAR2(15)) 的驻留列 loan_prod_type.resident 列的数据类型是什么?从错误开始,我认为它是某种形式的 NUMBER? 这是一个 VARRAY 类型名称,称为 RESIDENT_VARRRAY 【参考方案1】:

您遇到的错误是因为 SQL 类型与 PL/SQL 类型不同。

您在架构级别声明的 LOAN_PROD_TAB.RESIDENT 列的类型与您在 CBIS_LOAN_PROD_PACKAGE 包规范中声明的名为 RESIDENT_VARRAY 的类型不同。

为了使其工作,当您声明(和实例化)变量 V_T 时,您必须使用与声明 LOAN_PROD_TAB.RESIDENT 列时相同的类型。

以下是验证我的解决方案的完整示例:

CREATE OR REPLACE TYPE mem_type IS VARRAY(5) of VARCHAR2(15);

CREATE TABLE test_va (
  va_Name VARCHAR2(10),
  va_Address VARCHAR2(20),
  va_City VARCHAR2(20),
  va_Phone VARCHAR2(8),
  va_Members mem_type);

create or replace package test_va_pkg as
  TYPE p_mem_type IS VARRAY(5) of VARCHAR2(15); -- cannot be used to insert into test_va.va_Members column!!!!
  procedure p_test_va(
    p_name VARCHAR2,
    p_Address VARCHAR2,
    p_City VARCHAR2,
    p_Phone VARCHAR2
  );
end test_va_pkg;
/

create or replace package body test_va_pkg as
  procedure p_test_va(
    p_name VARCHAR2,
    p_Address VARCHAR2,
    p_City VARCHAR2,
    p_Phone VARCHAR2
  ) is 
--    v_members_va p_mem_type := p_mem_type('V_1','V_2','V_3','V_4','V_5'); -- doesn't work!
    v_members_va mem_type := mem_type('V_1','V_2','V_3','V_4','V_5');
  begin
    insert into test_va
    values (
      p_name,
      p_Address,
      p_City,
      p_Phone,
      v_members_va
    );

    commit;
  exception 
    when others then
      rollback;

      raise;

  end p_test_va;
end test_va_pkg;
/

begin
  test_va_pkg.p_test_va('Eric Smith', 'N/A', 'London', '12345679');
end;
/

select * from test_va;

希望对你有帮助!

【讨论】:

以上是关于通过包过程插入带有可变数组列的表时出错的主要内容,如果未能解决你的问题,请参考以下文章

可变数组(PLSQL)

允许角色查询、插入和更新可变数组

使用 Visual C++ 编译器 (Visual Studio 2010) 的可变数组大小出错。如何规避这个问题?

插入带有字符串的数组时,postgresql 查询会出错

由于带有 sequelize.js 的 UUID 外键,尝试将行插入表时出错

带有游标的 pl/sql 可变数组