Reputation: 1613
I have a CLOB
column that stores html
code. To parse it, I've written a Java stored function -
CREATE or replace FUNCTION parse_html(value in CLOB)
RETURN CLOB
AS LANGUAGE JAVA NAME 'MyClass.parse(java.lang.String) return java.lang.String';
and added a corresponding Java
class.
When I call this function parse_html(clob_col_name)
-
SELECT PARSE_HTML(m.clob_col_name)
FROM my_table m
where length(m.clob_col_name) > 4000;
I got the following error -
ORA-00932: inconsistent datatypes: expected a value at argument position 1 that is convertible to a Java java.lang.String got an Oracle CLOB 00932. 00000 - "inconsistent datatypes: expected %s got %s"
As I mentioned earlier, I need to parse the html
data using Jsoup
. jsoup.parse
expects String
as an argument. Therefore I need to convert Clob
to String
. Here is the parse method -
public static Clob parse(Clob clob) {
String value = clobToString(clob);
if (!isEmpty(value)) {
return stringToClob(Jsoup.parse(value).text().trim());
}
return null;
}
This method is doing the conversion from Clob
to String
-
private static String clobToString(Clob clob) {
StringBuilder sb = new StringBuilder();
if (clob == null) {
return null;
}
try {
Reader reader = clob.getCharacterStream();
BufferedReader br = new BufferedReader(reader);
String line;
while (null != (line = br.readLine())) {
sb.append(line);
}
br.close();
} catch (IOException e) {
// handle this exception
} catch (SQLException e) {
//e.printStackTrace();
}
return sb.toString();
}
And again I need to convert String
back to Clob
before returning the parsed value.
private static Clob stringToClob(String value) {
if (isEmpty(value)) {
return null;
}
Clob myClob = null;
try {
myClob = new SerialClob(value.toCharArray());
} catch (SQLException e) {
//e.printStackTrace();
}
return myClob;
}
While calling the function -
create or replace FUNCTION parse(value in CLOB)
RETURN CLOB
AS LANGUAGE JAVA NAME 'HtmlParser.parse(java.sql.Clob) return java.sql.Clob';
I got the following error -
ORA-00932: inconsistent datatypes: expected a return value that is an instance of a user defined Java class convertible to an Oracle type got an object that could not be converted
Since I used javax.sql.rowset.serial.SerialClob
to initialize Clob
. I don't want to use Connection
in this case. Is there any way around?
Upvotes: 1
Views: 1554
Reputation: 1
You can use connection, you don't need any additional data to create it. Here is my solution
import java.sql.Clob;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
public class TestClob {
public static Clob decode(Clob clobParam) throws SQLException {
String value = clobParam.getSubString(1, (int)(clobParam.length()));
Connection conn = DriverManager.getConnection("jdbc:default:connection:");
Clob cOut = conn.createClob();
cOut.setString(1, "Decoded " + value);
return cOut;
}
}
create or replace function TestClob(obj Clob) return Clob
as language java name 'TestClob.decode(java.sql.Clob) return java.sql.Clob';
Upvotes: 0
Reputation: 21095
Your declaration of the Java method in Oracle Java Stored Procedure using String
will work only for VARCHAR2
parameter.
here a simple example
create or replace and compile java source named "HelloVarchar" as
public class HelloVarchar
{
public static String world(String txt)
{
return "Hello " + txt;
}
};
/
CREATE or replace FUNCTION parse_varchar(value in VARCHAR2)
RETURN VARCHAR2
AS LANGUAGE JAVA NAME 'HelloVarchar.world(java.lang.String) return java.lang.String';
/
To use CLOB the option was to declare oracle.sql.CLOB
, but this class si apparently deprecated compensated with java.sql.Clob
Here a trivial example only passing the parameter back
create or replace and compile java source named "HelloClob" as
import java.sql.Clob;
import java.sql.SQLException;
public class HelloClob
{
public static Clob world(Clob txt) throws SQLException
{
return txt;
}
};
/
CREATE or replace FUNCTION parse_clob(value in CLOB)
RETURN CLOB
AS LANGUAGE JAVA NAME 'HelloClob.world(java.sql.Clob) return java.sql.Clob';
/
Upvotes: 2