我已经使用查询在Oracle中创建了一个Java存储过程:
CREATE OR REPLACE PROCEDURE GETSHEETROWS(I_file_id number, I_sheetNode clob,template_key varchar2 ,wksht_key varchar2 ,wksht_name varchar2 )
AS LANGUAGE JAVA
NAME 'SheetRowsJson.getSheetRows(int, java.sql.Clob, java.lang.String, java.lang.String, java.lang.String)';
/
以下是我的Java代码。 (输入I_sheetnode
是json类型。由于plsql中没有Jsontype
数据类型,因此我在这里使用了clob
,所以在这里也使用了相同的数据)
public static void getSheetRows( int I_file_id, Clob I_sheetNode, String
template_key, String wksht_key,String wksht_name ) {
try{
String url = "jdbc:oracle:thin:@xxxxx:port/yyyyy";
Connection conn = DriverManager.getConnection(url,"username","password");
System.out.println("-------------------Connection Successful--------------------------------");
String sheetRows = "select X.Node,X.rn from json_table (("+ I_sheetNode.toString() +"),'$.table_row[*]' COLUMNS(rn for ordinality,Node varchar2(4000) FORMAT JSON PATH '$')) X";
PreparedStatement ps=conn.prepareStatement(sheetRows);
ResultSet rs = ps.executeQuery();
/* Remaining code goes here */
当我尝试运行这样的过程时,
set serveroutput on;
call dbms_java.set_output(50);
execute GETSHEETROWS(14,'{"name":"sheet","table_row":[{"value":"1","item":"11111","id":"2","value":"1","action":"NEW"},{"value":"2","item":"22222","id":"3","value":"4","action":"NEW"}]}','TEMPLATE','SHEET','Sheet1');
/
我得到以下输出:
Call completed.
-------------------Connection Successful--------------------------------
java.sql.SQLSyntaxErrorException: ORA-01729: database link name expected
at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:450)
at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:399)
at oracle.jdbc.driver.T4C8Oall.processError(T4C8Oall.java:1059)
at oracle.jdbc.driver.T4CTTIfun.receive(T4CTTIfun.java:522)
at oracle.jdbc.driver.T4CTTIfun.doRPC(T4CTTIfun.java:257)
at oracle.jdbc.driver.T4C8Oall.doOALL(T4C8Oall.java:587)
at oracle.jdbc.driver.T4CPreparedStatement.doOall8(T4CPreparedStatement.java:225)
at oracle.jdbc.driver.T4CPreparedStatement.doOall8(T4CPreparedStatement.java:53)
at oracle.jdbc.driver.T4CPreparedStatement.executeForDescribe(T4CPreparedStatement.java:774)
at oracle.jdbc.driver.OracleStatement.executeMaybeDescribe(OracleStatement.java)
at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java)
at oracle.jdbc.driver.OraclePreparedStatement.executeInternal(OraclePreparedStatement.java)
at oracle.jdbc.driver.OraclePreparedStatement.executeQuery(OraclePreparedStatement.java)
at oracle.jdbc.driver.OraclePreparedStatementWrapper.executeQuery(OraclePreparedStatementWrapper.java)
at SheetRowsJson.getSheetRows(SheetRowsJson.java:25)
PL/SQL procedure successfully completed.
我无法找出原因。由于正在打印“连接成功”,连接真的成功吗?或不?如果没有,为什么?
注意:我已经使用loadjava
实用程序加载了Java类。
答案 0 :(得分:2)
如果您为生成的语句添加基本的调试打印信息,例如:
System.out.println(sheetRows);
您会看到类似的内容:
select X.Node,X.rn from json_table ((oracle.sql.CLOB@77556fd),'$.table_row[*]' COLUMNS(rn for ordinality,Node varchar2(4000) FORMAT JSON PATH '$')) X
toString()
方法显示的是对象ID,而不是字符串内容。并且该ID中的@
导致您看到错误(如77556fd
或您看到的任何值都不是有效的对象标识符)。
您可以嵌入实际传入的字符串值,但是必须将其用单引号引起来,并且数据库中字符串文字的大小(4k或32k,具体取决于版本)会受到限制和设置),这使得使用CLOB首先毫无意义;而且无论如何,您都应该使用绑定变量,例如:
sheetRows = "select X.Node,X.rn from json_table (?,'$.table_row[*]' COLUMNS(rn for ordinality,Node varchar2(4000) FORMAT JSON PATH '$')) X";
PreparedStatement ps=conn.prepareStatement(sheetRows);
ps.setClob(1, I_sheetNode);
ResultSet rs= ps.executeQuery();
我收到“ java.sql.SQLException:ORA-22922:不存在的LOB值”。
我最初是在DB外部进行测试,但确实看到了此设置,可以更完整地复制您的设置。到目前为止,我避免的唯一方法是避免隐式的临时CLOB:
create table t (c) as (
select to_clob('{"name":"sheet","table_row":[{"value":"1","item":"11111","id":"2","value":"1","action":"NEW"},{"value":"2","item":"22222","id":"3","value":"4","action":"NEW"}]}') from dual
);
declare
l_clob clob;
begin
select c into l_clob from t;
getsheetrows(14, l_clob, 'TEMPLATE', 'SHEET', 'Sheet1');
end;
/
答案 1 :(得分:0)
连接失败。
在所有情况下都会显示“ 连接成功 ”消息。即使getConnection返回null或错误,System.out.print仍将打印“ 连接成功 ”。
您可能想添加if语句或try catch语句以检查连接是否存在,而不是添加System.out.print语句,该语句不检查连接是否存在,而只会打印“连接”成功”
PS:检查您的网址和/或正在使用的罐子。