【问题标题】:issue in executing pl sql block through java通过java执行pl sql块的问题
【发布时间】:2017-10-18 06:20:32
【问题描述】:

我用java写了如下代码。

package demo;

import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Types;

public class Sample {

    private Connection c = null;

    public Sample()
    {
        try {
            c = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:XE", "system", "jboss");
            String plsql = ""+
            "declare"+
                    "x number;"+
            "begin "+
                    "select HEADCOUNT  FROM PROJECT where deptid=1;"+
            "end;";
            CallableStatement cs = c.prepareCall(plsql);
            //cs.registerOutParameter(0, Types.INTEGER);

            cs.execute();
            System.out.println("Result is "+cs.getInt(1));
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    public static void main(String[] args) 
    {
        Sample z = new Sample();
    }
}

我只是想探索一下我可以通过 java 执行 plsql 块的机制。 以上只是简单的查询。 在执行上面的java代码时,我得到错误

java.sql.SQLException: Invalid SQL type: sqlKind = UNINITIALIZED
    at oracle.jdbc.driver.T4CCallableStatement.doOall8(T4CCallableStatement.java:75)
    at oracle.jdbc.driver.T4CCallableStatement.executeForRows(T4CCallableStatement.java:1043)
    at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:1336)
    at oracle.jdbc.driver.OraclePreparedStatement.executeInternal(OraclePreparedStatement.java:3613)
    at oracle.jdbc.driver.OraclePreparedStatement.execute(OraclePreparedStatement.java:3714)
    at oracle.jdbc.driver.OracleCallableStatement.execute(OracleCallableStatement.java:4755)
    at oracle.jdbc.driver.OraclePreparedStatementWrapper.execute(OraclePreparedStatementWrapper.java:1378)
    at demo.Sample.<init>(Sample.java:26)
    at demo.Sample.main(Sample.java:36)

让我知道在执行此类 pl/sql 块之前是否需要任何事先设置。

【问题讨论】:

标签: java oracle jdbc plsql


【解决方案1】:

1) 第一个问题是其他答案中提到的declarex...
2) 第二个问题是select HEADCOUNT FROM PROJECT where deptid=1; 在plsql 中这个查询无效。应该是select HEADCOUNT into x ...

【讨论】:

    【解决方案2】:

    一些错误:

    1. 字符串将连接到declarex,您需要在它们之间留一个空格。
    2. 您没有从表INTO PL/SQL 变量中选择值。
    3. PL/SQL 块没有将值放入绑定变量以将其返回给 Java(如果直接使用绑定变量,则无需在 PL/SQL 中声明单独的变量)。李>
    4. 您已经注释掉了注册输出参数的行并且参数是 1-indexed(不是 0-indexed)。

    类似这样的:

    import java.sql.CallableStatement;
    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.SQLException;
    import java.sql.Types;
    
    public class Sample {
      public static void main( final String[] args ) 
      {
        try {
          Class.forName( "oracle.jdbc.OracleDriver" ); // If you are using the Oracle driver.
    
          Connection con = DriverManager.getConnection(
            "jdbc:oracle:thin:@localhost:1521:XE",
            "username",
            "password"
          );
    
          CallableStatement cs = con.prepareCall(
            "BEGIN SELECT HEADCOUNT INTO :1 FROM PROJECT WHERE deptid=1; END;"
          );
          cs.registerOutParameter( 1, Types.NUMERIC );
          cs.execute();
          System.out.println( cs.getInt( 1 ) );
        }
        catch ( ClassNotFoundException | SQLException ex )
        {
          System.err.println( ex.getMessage() );
        }
      }
    }
    

    【讨论】:

      【解决方案3】:

      在您的字符串中提供适当的空格以形成SQL 查询。这就是改变必要的空格后的样子!

      String plsql = "declare x number; "+
                      "begin "+
                         "select HEADCOUNT  FROM PROJECT where deptid=1; "+
                      "end;";
      

      您需要使用正确的空格更正您的代码,否则您想要传递的 SQL 将通过您的 Java / JDBC 代码出错。

      您可以将PL/SQL 代码更改为以下内容:

      CallableStatement cs = con.prepareCall(
          "BEGIN SELECT HEADCOUNT INTO :1 FROM PROJECT WHERE deptid=1; END;"
      );
      

      希望这能很好地回答您的问题!

      【讨论】:

        猜你喜欢
        • 2011-07-09
        • 2018-08-05
        • 1970-01-01
        • 2017-09-02
        • 2011-06-28
        • 1970-01-01
        • 1970-01-01
        • 2016-08-09
        • 1970-01-01
        相关资源
        最近更新 更多