通过 Rest API 调用存储过程字符串返回空而不是有效字符串
Posted
技术标签:
【中文标题】通过 Rest API 调用存储过程字符串返回空而不是有效字符串【英文标题】:calling Stored Procedure String via Rest API returns empty instead of valid String 【发布时间】:2019-11-19 10:12:11 【问题描述】:作为后端开发人员,我想调用连接Oracle 9i 数据库的存储过程来获取单个输出字符串。
实际上,输出参数的结果为字符串,返回空。
您能告诉我要对作品进行哪些修改吗?
这是我的休息控制器:
@GetMapping(value = "/third")
public String getVariable ()
String result = "" ;
Connection conn;
conn = getConnection() ;
CallableStatement cstmt = null;
try
String SQL = "call pkg1234.get_pc_lookup_value_second(?,?)";
cstmt = conn.prepareCall (SQL);
cstmt.setString(1, "TES");
cstmt.registerOutParameter(2, oracle.jdbc.OracleTypes.VARCHAR );
cstmt.execute();
String dddresult = cstmt.getString(2);
System.out.println(" Record :"+dddresult);
result = dddresult;
catch (SQLException e)
System.out.println(" go this");
e.printStackTrace();
return result ;
这是我的存储过程:
PROCEDURE get_pc_lookup_value_second (
i_lookup_code IN VARCHAR2,
o_lookup_value OUT VARCHAR2
)
o_lookup_value := '456';
END get_pc_lookup_value_second;
【问题讨论】:
你为什么在 Spring 中使用普通的 jdbc?在 spring 中有类似 jdbc 模板的方法可以轻松处理这类事情。 什么样的模板?我使用模板和 jpa 但无济于事。没有人回答我之前的问题,所以我使用原始方法 这个问题的大部分材料都莫名其妙地编辑成答案(!),这反过来又需要大量编辑,以区分问题作者和答案作者的声音。我断言答案中的材料意味着这个问题缺少minimal reproducible example,因此可以作为题外话关闭。 请不要在未来以这种方式添加细节 - 这会导致令人绝望的问答,并且在 Stack Overflow 的目标方面会适得其反。我们正在努力整理对未来广大读者有用的材料。 【参考方案1】:为了简单起见,试试我自己的库:
<dependency>
<groupId>com.github.buckelieg</groupId>
<artifactId>db-fn</artifactId>
<version>0.3.4</version>
</dependency>
然后在代码中:
try(DB db = new DB("your-connection-string"))
String result = db.procedure("call pkg1234.get_pc_lookup_value_second(?,?)", P.in("TES"), P.out(JDBCType.VARCHAR)).call(cs -> cs.getString(2)).orElse("Unknown");
查看更多here
您已将以下代码报告为您的代码:
try(DB db = new DB("jdbc:oracle:thin:username/password@10.8.12.6:1521:dev"))
String thisString = db.procedure("call b_pc_mob_portal_pkg.get_pc_lookup_value_second(?,?)",
P.in("TES" , "i_lookup_code"),
P.out(JDBCType.LONGNVARCHAR , "o_lookup_value" )).call(cs -> cs.getString(2)).orElse("Unknown");
System.out.println( "thisString String :" + thisString );
您报告说这会产生:
[Ljava.lang.Object;无法转换为 [Lbuckelieg.fn.db.P;
你问过:
如何检查此方法是否需要修改。
这是因为您尝试将命名参数与匿名参数结合起来。要么删除参数名称:
db.procedure("call b_pc_mob_portal_pkg.get_pc_lookup_value_second(?,?)", P.in("TES"), P.out(JDBCTtype.VARCHAR))...
或在过程调用语句中添加名称:
db.procedure("call b_pc_mob_portal_pkg.get_pc_lookup_value_second(:i_lookup_code,:o_lookup_value)", P.in("i_lookup_code", "TES"), P.out(JDBCType.VARCHAR , "o_lookup_value" ))...
您还报告说您已尝试过此代码:
try(DB db = new DB("jdbc:oracle:thin:username/password@10.8.12.6:1521:dev"))
String thisString = db.procedure("call b_pc_mob_portal_pkg.get_pc_lookup_value_second(?,?)",
P.in("TES" ),
P.out(JDBCType.VARCHAR )).call(cs -> cs.getString(2)).orElse("Unknown");
System.out.println( "thisString String :" + thisString );
你说过:
当我这样做时,它会给出:
buckelieg.fn.db.SQLRuntimeException:[registerOutParameter 未实现]
我认为问题出在 JDBC 驱动程序中。您使用哪个版本?可以更新换新的吗?
你说过这是你的数据库:
还有你下载的:
OJDBC7.jar
https://www.oracle.com/database/technologies/jdbc-drivers-12c-downloads.html
这是 Oracle SQL Developer 获取的 Oracle IDE 版本
非常有趣。我会研究这个问题。
作为临时解决方法,我建议执行以下操作:
重写过程如下:
CREATE OR REPLACE FUNCTION b_pc_mob_portal_pkg.get_pc_lookup_value_second(IN param1 VARCHAR2 DEFAULT 'TES')
RETURN VARCHAR2 IS
BEGIN
RETURN '456';
END b_pc_mob_portal_pkg.get_pc_lookup_value_second;
然后在代码中:
String value = db.select("SELECT b_pc_mob_portal_pkg.get_pc_lookup_value_second(?) AS output FROM DUAL", "TES").single(rs -> rs.getString("output")).orElse("Unknown");
流程怎么样?
您是否尝试过最新版本 (0.3.6) 的库?
<dependency>
<groupId>com.github.buckelieg</groupId>
<artifactId>db-fn</artifactId>
<version>0.3.6</version>
</dependency>
【讨论】:
我已更新答案以粘贴我的工作。请帮我看看有没有异常 这是因为您尝试将命名参数与匿名参数结合起来。 将命名参数与数字混合? 将java更新到版本8,使原始代码(带有过程的代码)工作 能否请您针对上述错误发布堆栈跟踪或在 github 项目中创建问题?【参考方案2】:@raju, 它可以帮助你,使用带有 Springboot 注释的 Jpa 模板。
Controller class
@Autowired
B b;
@GetMapping(value = "/third")
public String getVariable ()
return b.getInfo();
@service
B
@Autowired
A a;
public String getInfo()
return a.getoutput();
@repository
interface A extends JpaRepository<Mention your Entity,String>()
@procedure(name="Execute your_procedure name")
//return type
public String getoutput();
【讨论】:
以上是关于通过 Rest API 调用存储过程字符串返回空而不是有效字符串的主要内容,如果未能解决你的问题,请参考以下文章
在 Azure 存储 [REST] [Azure Blob] 中对 PUT Blob 的 REST api 调用中的身份验证失败
如何对 REST api 执行异步 axios 调用并更新存储(redux thunk 令人困惑)?