【问题标题】:Passing object types to Oracle stored procedure gives "Invalid name pattern" error将对象类型传递给 Oracle 存储过程会出现“无效名称模式”错误
【发布时间】:2015-07-26 04:52:33
【问题描述】:

Oracle 数据库管理员为我提供了一个存储过程。它采用 (IN) varchar 并提供 RECORD 类型。记录类型如下:

TYPE BAL_RECORD_TYPE IS RECORD
(
  ac_no               VARCHAR2 (50),
  Account_type        VARCHAR2 (50),
  ac_status           VARCHAR2 (10),
  cur_code            VARCHAR2 (5),
  available_balance   NUMBER
);

我已经按照下面的链接在我的 jdbc 应用程序中支持 RECORD 类型。 http://betteratoracle.com/posts/31-passing-record-types-between-oracle-and-java

从上面的文章我改变了

stmt.registerOutParameter(2, OracleTypes.STRUCT, "RECTYPE");

stmt.registerOutParameter(2, OracleTypes.STRUCT, "BAL_RECORD_TYPE");

因为 BAL_RECORD_TYPE 是我的记录名称。

但我收到以下错误:

invalid name pattern: APPADMIN.BAL_RECORD_TYPE

这里 APPADMIN 是数据库的用户名。我不知道它如何与 OUT 参数绑定。

我的问题是:

  1. 我可以遵循任何好的示例代码来支持 RECORD 类型的 oracle 吗?

  2. 错误的可能原因是什么(无效的名称模式:APPADMIN.BAL_RECORD_TYPE)?

加法:

  1. 对于我的 oracle 数据库管理员来说,实现 CURSOR 类型而不是 RECORD 类型有多难?

【问题讨论】:

  • 那篇文章的标题具有误导性。模式级对象类型和 PL/SQL 定义的记录类型之间存在显着差异。据我所知,您不能将 PL/SQL 类型用于 STRUCT,即使您将定义它的包名称作为名称的一部分 (APPADMIN.PKG.BAL_RECORD_TYPE),您也只能使用模式级类型..
  • 您对更改文章标题有什么建议吗?
  • “传递对象类型...”?我可以理解为什么我认为可能会使用该术语;但它们有特定的含义,并且拥有一个名为“recType”的对象本身就令人困惑。

标签: java oracle jdbc oracle11g oracle-sqldeveloper


【解决方案1】:

我找到了问题所在。其实,这不属于我。我们的 oracle DB 管理员在包中定义了无法从 JAVA 访问的类型。

摘录如下: 我们不能调用在 ORACLE 的包中定义的类型。 Java 无法访问该类型,但 sqlplus 可以访问。所以,我们的 DB Administrator 最终定义了包外的类型。

我从这里找到了这个解决方案:

http://forum.spring.io/forum/spring-projects/data/34668-array-as-out-parameter-java-sql-sqlexception-ora-06550-line-1-column-7

【讨论】:

    【解决方案2】:

    不幸的是,您不能将 PL/SQL RECORD 类型传递给存储过程,或者直接使用 JDBC 从存储过程中获取它。但是你可以在这里使用这个技巧来解决这个限制:

    DELARE
      rec APPADMIN.BAL_RECORD_TYPE;
    BEGIN
      my_proc(some_input, rec);
      ? := rec.ac_no;
      ? := rec.account_type;
      ? := rec.ac_status;
      ? := rec.cur_code;
      ? := rec.available_balance;
    END;
    

    您现在可以按如下方式调用您的过程:

    try (CallableStatement s = con.prepareCall(" ... above PL/SQL code ...")) {
    
        // Register each of your record's individual attribute types:
        s.registerOutParameter(1, Types.VARCHAR);
        s.registerOutParameter(2, Types.VARCHAR);
        s.registerOutParameter(3, Types.VARCHAR);
        s.registerOutParameter(4, Types.VARCHAR);
        s.registerOutParameter(5, Types.NUMERIC);
    
        s.execute();
    
        // Fetch each of your record's individual attribute types:
        String acNo = s.getString(1);
        String accountType = s.getString(1);
        String acStatus = s.getString(1);
        String curCode = s.getString(1);
        BigDecimal availableBalance = s.getBigDecimal(1);
    }
    

    I've recently blogged about this technique more in detail。如果您有许多采用 RECORD 类型 IN/OUT 参数的过程/函数,该博客文章还包含有关如何自动化此技术的更多信息。

    【讨论】:

      猜你喜欢
      • 2017-06-08
      • 2010-10-26
      • 2014-03-02
      • 1970-01-01
      • 1970-01-01
      • 2020-05-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多