【问题标题】:Getting "ORA-03115: unsupported network datatype or representation" error while fetching array of varchar from anonymous pl/sql从匿名 pl/sql 获取 varchar 数组时出现“ORA-03115:不支持的网络数据类型或表示”错误
【发布时间】:2015-04-19 04:37:26
【问题描述】:

我在从匿名 PL/SQL 块中获取类型的可变数组时收到“ORA-03115:不支持的网络数据类型或表示”异常。

我的代码是:

    Connection con = null;
    CallableStatement cstmt = null;
    ResultSet rs = null;
    String dequeueQuery = "DECLARE " +
            " type namesarray IS VARRAY(5) OF VARCHAR2(10); " +
            " names namesarray;" +
            "   total integer;" +
            "   BEGIN " +

            "   names := namesarray('Kavita', 'Pritam', 'Ayan', 'Rishav', 'Aziz'); " +

            "   ? := names;"+

            " END;";

    try{

            con = getConnection();

            con.setAutoCommit(false);

            cstmt =(OracleCallableStatement )con.prepareCall(dequeueQuery);
            cstmt.registerOutParameter(1, OracleTypes.ARRAY);
            boolean b = cstmt.execute();
            Array arr = cstmt.getArray(1);

              String[] recievedArray = (String[]) arr.getArray();
              for (int i = 0; i < recievedArray.length; i++)

                System.out.println(recievedArray[i]);

            con.commit();

    }catch (Exception e) {
        try {
            con.rollback();
        } catch (SQLException e1) {
            e1.printStackTrace();
        }`

请帮助我。提前谢谢你。

【问题讨论】:

    标签: java sql oracle jdbc


    【解决方案1】:

    我认为你正在使用 ojdbc14.jar

    ojbc6.jar 尝试一次,它应该可以工作。

    【讨论】:

      【解决方案2】:

      java.sql.SQLException: ORA-03115: 不支持的网络数据类型或 表示

      这是由以下语句引起的:

      cstmt.registerOutParameter(1, OracleTypes.ARRAY);
      

      该语句说数组将是输出,但没有将实际的 Oracle 类型名称指定为第三个参数。您可以查看Oracle Doc 了解更多信息。

      我们可以通过添加具有实际 Oracle 类型名称的第三个参数来修复异常“java.sql.SQLException: ORA-03115: unsupported network datatype or representation”。在您的情况下,它是NAMESARRAY

      cstmt.registerOutParameter(1, OracleTypes.ARRAY,"NAMESARRAY");
      

      但是上面的语句在运行时会抛出以下异常:

      java.sql.SQLException:无效的名称模式:SCOTT.NAMESARRAY

      这是因为我们没有在 DB 中声明类型 NAMESARRAY。上述异常表示用户为 SCOTT,但您可以连接到您选择的用户并创建类型。

      在 DB 中创建类型:

      connect scott/tiger
      CREATE OR REPLACE TYPE namesarray AS VARRAY(5) OF VARCHAR2(10) ;
      /
      

      一旦我们创建了NAMESARRAY 类型,如果我们在不更改的情况下执行您的代码,我们将遇到以下错误:

      java.sql.SQLException:ORA-06550:第 1 行,第 180 列:

      PLS-00382:表达式类型错误 ORA-06550:第 1 行,第 173 列:

      PL/SQL:语句被忽略

      这个错误是因为我们已经在用户级别定义了类型,但是我们试图在下面的代码块中再次创建类型:

      String dequeueQuery = "DECLARE " +
                  " type namesarray IS VARRAY(5) OF VARCHAR2(10); " +
                  " names namesarray;" +
                  "   total integer;" +
                  "   BEGIN " +
                  "   names := namesarray('Kavita', 'Pritam', 'Ayan', 'Rishav', 'Aziz'); " +
                  "   ? := names;"+
                  " END;";
      

      因此,我们需要从中删除类型声明。

      String dequeueQuery = "DECLARE " +
                  " names namesarray;" +
                  "   total integer;" +
                  "   BEGIN " +
                  "   names := namesarray('Kavita', 'Pritam', 'Ayan', 'Rishav', 'Aziz'); " +
                  "   ? := names;"+
                  " END;";
      

      如果我们在编译后执行程序,去掉它,应该可以看到如下输出:

      Kavita
      Pritam
      Ayan
      Rishav
      Aziz
      

      以下是更新后的程序:

      import java.io.*;
      import java.sql.*;
      import oracle.jdbc.*;
      
      public class DBQC {
         public static void main(String[] args) {
         try {
            Connection con=null;
            Class.forName("oracle.jdbc.OracleDriver");
            String connStr = "jdbc:oracle:thin:scott/tiger@//dbhost:1521/dbsrvc";
            con=DriverManager.getConnection(connStr);
            if(con != null)
            {
               System.out.println("Connection succeeded");
      
               String dequeueQuery = "DECLARE " +
                  " names namesarray;" +
                  "   total integer;" +
                  "   BEGIN " +
                  "   names := namesarray('Kavita', 'Pritam', 'Ayan', 'Rishav', 'Aziz'); " +
                  "   ? := names;"+
                  " END;";
      
               CallableStatement cstmt = null;
               con.setAutoCommit(false);
               cstmt =(OracleCallableStatement)con.prepareCall(dequeueQuery);
      
               cstmt.registerOutParameter(1, OracleTypes.ARRAY,"NAMESARRAY");
               boolean b = cstmt.execute();
               Array arr = cstmt.getArray(1);
      
               String[] recievedArray = (String[]) arr.getArray();
               for (int i = 0; i < recievedArray.length; i++)
                   System.out.println(recievedArray[i]);
      
               con.commit();
            }
            con.close();
          } catch(Exception e){e.printStackTrace();}
          }
      }
      

      【讨论】:

      • 非常感谢,但我们没有为我们的用户创建权限,这就是我声明类型的原因。我们是否有替代方法来避免创建类型?
      • 对不起,如果使用 varray,我想不出替代方法。要创建新的type,用户需要resource 权限。如果用户已经拥有resource 权限,那么创建一次类型将解决您的所有问题。如果有什么想法,我一定会分享。祝你好运。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-08-19
      • 2021-03-03
      • 2021-07-02
      • 1970-01-01
      • 2018-11-30
      • 1970-01-01
      • 2020-03-22
      相关资源
      最近更新 更多