【问题标题】:Callablestatement error : Missing IN or OUT parameter at index:: 1Callablestatement 错误:索引处缺少 IN 或 OUT 参数:: 1
【发布时间】:2014-03-19 18:40:12
【问题描述】:

我正在尝试运行 Oracle 的 CREATE JAVA 语句。

我们不得不将 CallableStatement.setEscapeProcessing 设置为 false 以避免出现问号问题。这适用于我们的大多数语句,但在 Java switch 语句的情况下,我们得到以下异常:

java.sql.SQLException:索引处缺少 IN 或 OUT 参数:: 1

我想这与 switch 语句中使用的冒号有关。

这是一个问题的例子:

JDBCTest.java

package jdbctest;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.DriverManager;

public class JDBCTest {

    public static void main(String[] args) throws Exception {
        String data = readScript("/tmp/Demo.sql");        

        Connection conn = null;
        CallableStatement callStat = null;
        try {
            String driver = "oracle.jdbc.driver.OracleDriver";
            String url = "jdbc:oracle:thin:@193.53.40.220:1521:ora11";
            String username = "";
            String password = "";

            Class.forName(driver);
            conn = DriverManager.getConnection(url, username, password);
            conn.setAutoCommit(false);
            callStat = conn.prepareCall(data);
            callStat.setEscapeProcessing(false);
            callStat.execute();
        } finally {
            try {callStat.close();} catch (Exception ex){}
            try {conn.close();} catch (Exception ex){}
        }

    }

    private static String readScript(String filename) throws IOException
    {
        StringBuilder stringBuilder = new StringBuilder();
        BufferedReader reader = null;
        try {
            String currentLine;
            reader = new BufferedReader(new InputStreamReader(
                    new FileInputStream(filename), "ISO-8859-1"));

            while ((currentLine = reader.readLine()) != null) {
                currentLine = currentLine.replaceAll("^\\s+$", "");
                currentLine = currentLine.replaceAll("\\s+$", "");
                stringBuilder.append(currentLine).append("\n");
            }
        } finally {
            try { reader.close();} catch (Exception ex) {}            
        }

        return stringBuilder.toString();
    }

}

Demo.sql

CREATE OR REPLACE JAVA SOURCE NAMED "jdbctest" AS

package jdbctest;

public class Demo {
    public void test()
    {
        int a = 3;
        switch (a)
        {
            case 1: System.out.println("1"); break;
            case 2: System.out.println("2"); break;
            case 3: System.out.println("3"); break;
        }
    }
}

这是在 11gR2 Oracle 数据库上使用 ojdbc6.jar(作为 JDBC 驱动程序)运行的。

【问题讨论】:

  • 去掉冒号还能用吗?最后一个字符/ 不是 PLSQL 命令,而是 SQL*Plus 命令,在 java 中不太可能工作。
  • 我的错。我们通常在针对数据库运行 PL/SQL 代码之前对其进行各种格式化。结尾/ 通常会被删除。我编辑了我的问题以删除/。删除冒号后,代码运行良好。
  • 如果您使用常规的Statement 而不是CallableStatement,它是否有效?
  • 确实如此! statement = conn.createStatement(); statement.setEscapeProcessing(false); statement.execute(data); 成功了!请发布您的答案,以便我接受。

标签: java sql oracle jdbc


【解决方案1】:

如果您使用Statement 而不是CallableStatement,它应该可以工作。

您应该将Statement 用于所有 DDL,PreparedStatement 用于 DML,CallableStatement 用于过程调用。创建过程是 DDL。

CallableStatement 将尝试检测并绑定由冒号 : 标识的变量,因此这可能就是您的代码无法正常工作的原因。

【讨论】:

  • 请注意,没有 Statement.setEscapeProcessing(false) 我有以下错误:Non supported SQL92 token at position [...]。谢谢文森特!
  • 您还需要setEscapeProcessing(false)Statement吗?
  • 是的,如果我不这样做,它会抱怨Non supported SQL92 token at position [...]
猜你喜欢
  • 2014-04-26
  • 1970-01-01
  • 2012-08-05
  • 1970-01-01
  • 2022-01-20
  • 1970-01-01
  • 2022-08-22
  • 1970-01-01
  • 2018-01-31
相关资源
最近更新 更多