Java 在Oracle上调用存储过程引发ORA-06550异常
我已经使用jdbc连接编写了一个简单的测试,我试图理解失败和可能的错误Oracle语法。从我的理解来看,这应该行得通,在互联网上搜索几个小时并没有发现太多反驳这一点 简单存储过程:Java 在Oracle上调用存储过程引发ORA-06550异常,java,oracle,stored-procedures,Java,Oracle,Stored Procedures,我已经使用jdbc连接编写了一个简单的测试,我试图理解失败和可能的错误Oracle语法。从我的理解来看,这应该行得通,在互联网上搜索几个小时并没有发现太多反驳这一点 简单存储过程: CREATE OR REPLACE PROCEDURE printHelloWorld (in_param_one IN VARCHAR2, out_param_one OUT VARCHAR2) AUTHID CURRENT_USER IS BEGIN out_param_one :
CREATE OR REPLACE PROCEDURE printHelloWorld
(in_param_one IN VARCHAR2, out_param_one OUT VARCHAR2)
AUTHID CURRENT_USER IS
BEGIN
out_param_one := 'Hello World';
END;
测试1:
@试验
公共void TestOracleStoredProcedureWithindex引发SQLException{
...
Connection con=DriverManager.getConnectionhost,props;
java.sql.CallableStatement cstmt=con.prepareCallBEGIN printHelloWorldin_param_one=>?,out_param_one=>?;END;;
oracle.jdbc.internal.OracleCallableStatementcstmt.SetString,测试;
oracle.jdbc.internal.OracleCallableStatementcstmt.registerOutParameter2,java.sql.Types.VARCHAR;
java.sql.PreparedStatementcstmt.execute;
...
}
测试2:
@试验
公共void testOracleStoredProcedureWithNamedParameters引发SQLException{
...
Connection con=DriverManager.getConnectionhost,props;
java.sql.CallableStatement cstmt=con.prepareCallBEGIN printHelloWorldin_param_one=>?,out_param_one=>?;END;;
oracle.jdbc.internal.OracleCallableStatementcstmt.setString\u param\u one,测试;
oracle.jdbc.internal.OracleCallableStatementcstmt.registerOutParameterout_param_one,java.sql.Types.VARCHAR;
java.sql.PreparedStatementcstmt.execute;
}
运行这两个测试时,Test1通过,Test2失败。我从Test2中得到的失败如下:
Caused by: Error : 6550, Position : 55, Sql = BEGIN procPrintHelloWorld2(in_param_one => IN_PARAM_ONE=>:0, out_param_one => OUT_PARAM_ONE=>:1); END;, OriginalSql = BEGIN procPrintHelloWorld2(in_param_one => ?, out_param_one => ?); END;, Error Msg = ORA-06550: line 1, column 56:
PLS-00103: Encountered the symbol ">" when expecting one of the following:
. ( ) , * @ % & = - + < / > at in is mod remainder not rem
<an exponent (**)> <> or != or ~= >= <= <> and or like like2
like4 likec between || multiset member submultiset
ORA-06550: line 1, column 92:
PLS-00103: Encountered the symbol ">" when expecting one of the following:
. ( ) , * @ % & = - + < / > at in is mod remainder not rem
<an exponent (**)> <> or != or ~= >= <= <> and or like like2
like4 likec between || multiset member submultiset
at oracle.jdbc.driver.T4CTTIoer11.processError(T4CTTIoer11.java:494)
我在某个地方读到,我不应该使用:VAR语法,但更改为:VAR语法确实可以让它工作。。。有谁比我更熟悉甲骨文的人能指出我做错了什么吗
谢谢 您在输出中看到了这一点吗
procPrintHelloWorld2(in_param_one => IN_PARAM_ONE=>:0, out_param_one => OUT_PARAM_ONE=>:1)
它将你的命名参数增加一倍,以?在原始SQL中,并将其替换为in_PARAM_ONE=>:0以获取in_PARAM_ONE=>in_PARAM_ONE=>:0
如果您从SQL字符串中删除这些内容,我认为无论哪种方式都可以正常工作
java.sql.CallableStatement cstmt = con.prepareCall("BEGIN printHelloWorld(?, ?); END;");
谢谢你的回复!这确实让它起作用了。。。但为什么它要将命名参数加倍?我已经可以使用BEGIN printHelloWorld:in_param_one,:out_param_one来运行这个测试;终止语法。但是,我想知道为什么它不能像我写的那样工作。如果使用索引参数,它会替换第一个?在带有Test的SQL字符串中,因此您的SQL以_param_one=>'Test'结束,并且工作正常。如果使用命名参数,它将替换第一个?使用IN_PARAM_ONE=>:0,但是您的SQL中已经有IN_PARAM_ONE=>了,所以现在它出现了两次,这是不正确的。您正在描述Oracle jdbc驱动程序构造的SQL不正确的原因。我同意in_param_one=>in_param_one=>:0是不正确的,但我不是在构造这个SQL。开始打印HelloWorld?;终止其中不包含任何命名参数!这不是问题的解决方案。不能在语句上设置命名参数,必须依赖于按特定顺序提供它们!如果不想按特定顺序设置命名参数,则不要将它们包含在SQL字符串中。开始打印HelloWorld?;终止不包含任何命名参数,除非调用.setString\u param\u one,Test。调用该函数将替换第一个?使用in_param_one=>'Test'时,如果要按特定顺序设置命名参数,该怎么办?