Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/384.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 在Oracle上调用存储过程引发ORA-06550异常_Java_Oracle_Stored Procedures - Fatal编程技术网

Java 在Oracle上调用存储过程引发ORA-06550异常

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 :

我已经使用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 := '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'时,如果要按特定顺序设置命名参数,该怎么办?