通过 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 调用中的身份验证失败

PayPal Rest API 直接付款

如何对 REST api 执行异步 axios 调用并更新存储(redux thunk 令人困惑)?

webpack服务器中的rest API调用(来自角度)返回401

如果通过rest api发布资源,是不是必须存储资源?

Rest api有时返回字符串有时返回json对象