How to Insert in Oracle using java - java

I am having CLOB column in Oracle Data Base , I want to insert String .
It works if I use setCharacterStream, but how to insert String by setBytes am getting exception.
Please help me.
String s = "Hello How are you Data for CLOB column";
ps.setCharacterStream(1, new StringReader(s), s.length());
ps.setByte(1,Byte.parseByte(s));
Exception Trace :
java.lang.NumberFormatException: For input string: "Hello How are you Data for CLOB column"
at java.lang.NumberFormatException.forInputString(NumberFormatException.java:48)
at java.lang.Integer.parseInt(Integer.java:447)
at java.lang.Byte.parseByte(Byte.java:151)
at java.lang.Byte.parseByte(Byte.java:108)
at colb.test.InertClob.main(InertClob.java:24)

Here are two good examples (with sample code, for select and insert):
Handling CLOBS made easy:
http://rocksolutions.wordpress.com/2010/06/07/handling-clobs-made-easy-with-oracle-jdbc-10g/
Adding large object type to databaase
http://docs.oracle.com/javase/tutorial/jdbc/basics/blob.html

please refer to the Java API DOC
Parses the string argument as a signed decimal byte. The characters in the string must all be decimal digits,

You should:
Turn the String to a byte array by calling s.getBytes() for example or any other.
Call setBytes method, not setByte
When retrieving from the database, don't forget how you got the bytes, in order to restore the String properly.

Related

convert byte array to java.sql.Clob

Is there any way to convert a byte array into java.sql.Clob ?
I am having this type of issue...
getHibernateTemplate().save(object)
Where object is having a field private Clob docData; and the similar is mapped into oracle table as CLOB
This docData clob is getting formed from somewhere in my java code like Hibernate.createClob(someString)
I tried to save it with type="clob" but getting cann't cast com.sun.proxy$Proxy124 to oracle.sql.CLOB. I have tried many ways to remove this Proxy but finally failed.
So I have decided to go like byte[] data = IOUtils.toByteArray(docData.getCharacterStream()); / byte[] data = IOUtils.toByteArray(docData.getAsciiStream()) and saving it as type="binary" but I am getting Caused by: java.sql.BatchUpdateException: ORA-01461: can bind a LONG value only for insert into a LONG column.
So now I want to create as a Clob from byte[].
Any help welcome.
Note earlier I was using Hibernate 3.3 and it was working fine without any such byte array conversion and etc...now I have upgraded to Hibernate 3.6.10 and getting this issue.
I'm using this method to create Blobs:
org.hibernate.engine.jdbc.NonContextualLobCreator.NonContextualLobCreator.INSTANCE.createBlob( buffer )
where buffer is an array of bytes.
There are 2 similar methods for creating CLOBs:
NonContextualLobCreator.INSTANCE.createClob( reader, length )
NonContextualLobCreator.INSTANCE.createClob( string )
Pick the one that fits better with your data.
Your error message says
cann't cast com.sun.proxy$Proxy124 to oracle.sql.CLOB
In the rest of your text you are referring to java.sql.Clob Check your imports, you might be using the clob from the oracle.sql package instead of the java.sql package somewhere.
Well, issue is resolved. I kept the java data type as 'Clob' only and made the hibernate mapping like type="string". Issue got resolved since my digital sign data does not contain more than 2 MB (that java string max supports).

How to invoke stored function in java of PostgreSQL database with JDBCTemplate

I have a stored function that takes below arguments in database.
CREATE OR REPLACE FUNCTION
public.abc(
id integer,
title text,
description text,
valid_until_date timestamp with time zone,
user_is_ext boolean,
remarks text)
{
//statements
}
I need to invoke this stored function. I am able to invoke directly in database using below query:
select "abc" (0,'title','description','2010-01-01 00:00:00+01',false,'text')
However i am not able to invoke using JDBC template in my SpringBoot application.
String sql="select \"abc\" (?,?,?,?,?,?)";
List<Integer> ids=jdbcTemplate.query(sql,new Object[]{id,myObj.getTitle(), myObj.getDescription(), myObj.getValidDate(), myObj.isUserExt(), ,myObj.getRemarks()},new BeanPropertyRowMapper(Integer.class));
Can someone help me to figure out what is it that I am missing?
i get "The column index is out of range:" error.
I tried using "update" instead of "query"
int ind=jdbcTemplate.update(sql, id,myObj.getTitle(), myObj.getDescription(), myObj.getValidUntilDate(), myObj.isUserExt(), myObj.getRemarks());
then i get following error
""2017-07-10 14:51:16 [http-bio-8080-exec-60] ERROR c.s.k.l.exceptions.ExceptionHandlers --- A result was returned when none was expected. –
tried using SimpleJDBC call as mentioned on the comment. getting below error while passing timestamp as a parameter in SQLParameter object
""2017-07-10 16:18:16 [http-bio-8080-exec-97] ERROR c.s.k.l.exceptions.ExceptionHandlers --- Bad value for type timestamp : org.springframework.jdbc.core.SqlParameter#3a4cbd06
Finally i resolved it!!
In my case I'm trying to invoke a stored function that returns an integer value. please find the code snippet below.
String sql="select * from \"stored_function_name\" (?,?,?,?,?,?,?,?,?)";
Integer result=jdbcTemplate.queryForObject(sql,Integer.class, new Object[] {all input parameters separated by coma});
Similarly we can use other variants of query.
Please make sure the parameters that you pass to function should have same datatype as in postgres database. If its a timestamp in db and you have date as string, you can convert it to timestamp using below code
Timestamp.valueOf("date_string in yyyy-mm-dd hh:mm:ss format")
Thank you everyone!!

Converting cassandra blob type to string

I have an old column family which has a column named "value" which was defined as a blob data type. This column usually holds two numbers separated with an underscore, like "421_2".
When im using the python datastax driver and execute the query, the results return with that field parsed as a string:
In [21]: session.execute(q)
Out[21]:
[Row(column1=4776015, value='145_0'),
Row(column1=4891778, value='114_0'),
Row(column1=4891780, value='195_0'),
Row(column1=4893662, value='105_0'),
Row(column1=4893664, value='115_0'),
Row(column1=4898493, value='168_0'),
Row(column1=4945162, value='148_0'),
Row(column1=4945163, value='131_0'),
Row(column1=4945168, value='125_0'),
Row(column1=4945169, value='211_0'),
Row(column1=4998426, value='463_0')]
When I use the java driver I get a com.datastax.driver.core.Row object back. When I try to read the value field by, for example, row.getString("value") I get the expected InvalidTypeException: Column value is of type blob. Seems like the only way to read the field is via row.getBytes("value") and then I get back an java.nio.HeapByteBuffer object.
Problem is, I cant seem to convert this object to string in an easy fashion. Googling yielded two answers from 2012 that suggest the following:
String string_value = new String(result.getBytes("value"), "UTF-8");
But such a String constructor doesn't seems to exist anymore.
So, my questions are:
How do I convert HeapByteBuffer into string?
How come the python driver converted the blob easily and the java one did not?
Side Note:
I could debug the python driver, but currently that seems too much work for something that should be trivial. (and the fact that no one asked about it suggests Im missing something simple here..)
Another easier way is to change the CQL statement.
select column1, blobastext(value) from YourTable where key = xxx
The second column would be type of String.
You can also get direct access to the Java driver's serializers. This way you don't have to deal with low-level details, and it also works for other types.
Driver 2.0.x:
String s = (String)DataType.text().deserialize(byteBuffer);
Driver 2.1.x:
ProtocolVersion protocolVersion = cluster.getConfiguration().getProtocolOptions().getProtocolVersion();
String s = (String)DataType.text().deserialize(byteBuffer, protocolVersion);
Driver 2.2.x:
ProtocolVersion protocolVersion = cluster.getConfiguration().getProtocolOptions().getProtocolVersion();
String s = TypeCodec.VarcharCodec.instance.deserialize(byteBuffer, protocolVersion);
For version 3.1.4 of the datastax java driver the following will convert a blob to a string:
ProtocolVersion proto = cluster.getConfiguration().getProtocolOptions().getProtocolVersion();
String deserialize = TypeCodec.varchar().deserialize(row.getBytes(i), proto);
1.) Converting from byte buffer in Java is discussed in this answer.
2.) Assuming you're using Python 2, it's coming back as a string in Python because str is the binary type.

CLOB to binarystream conversion

How to convert Clob data to Binarystream ?
I can able to find it in 2 steps as of now, 1--> CLOB to String 2---> String to BinaryStream.
I am calling a SQL package which has 1 i/p and 2 o/p and assigning the CLOB output to some variable XYZ, sample is shown below...
Clob XYZ=null;
CallableStatement CalSmt = null;
InputStream ABC = null;
try
{
CalSmt = conn.prepareCall("{call package(?,?,?)}");
CalSmt.registerOutParameter(1,OracleTypes.CLOB);
CalSmt.registerOutParameter(2,OracleTypes.INTEGER);
CalSmt.setString(3,"315141");
CalSmt.execute();
XYZ = CalSmt.getClob(1);
ABC= **XYZ.getBinaryStream();** <---- this is showing me a error as 'Method "getBinaryStream" not found'
}
Here XYZ is holding the CLOB data which needs to be converted to Binary Stream and Saved into ABC for further references. Kindly help me out by providing a single method for this plz. Thanks in Advance.
Yes, there's no getBinaryStream method on Clob, because it doesn't make sense for there to be one. A clob is character data, not binary data. It makes no more sense to ask a clob for a binary stream than it does to ask a blob for a character stream.
Your approach of converting to a string seems reasonable to me, to be honest, if you really need this conversion. It would be better if you could just avoid it though - if you're storing binary data, use a blob and InputStream everywhere. If you're storing character data, use a clob and Reader everywhere.

Passing String value to SQL bigint column

Given following Statment:
String query = "Select * from T_spareParts where SparePartPK IN (? )"
In my BackBean (JSF 2) I first iterate through all cars in table and build a String of all the cars currently selected (by picking each cars ID as primary key) so the final String before being passed to SQL could look like:
String finalString = " '1','2','3','4'";
And then :
this.prepareStatement= this.connection.prepareStatement(query);
this.prepareStatement.setString(1,finalString);
this.prepareStatement.executeQuery();
Exception thrown is:
Error converting data type nvarchar to bigint.
Now my understanding is that exception is due to SparePartPK is type bigint and we're passing a String .
But in SQL Server (2008) i can do :
Select * from T_spareParts where SparePartPK IN ('1','2','3','4')"
which returns results as expected. Why am i getting the exception and how can i correct the issue? (also feel free to comment if this isn't the best approach)
Update:
I've also tried to produce the finalString without single quotes which causes the same exception to be thrown :
String finalString = " 1,2,3,4";
You should put the numbers into an array (not a string), and use preparedStatement.setArray()
Thanks for the suggestions. Though as an alternative I created a StoredProcedure where it takes one parameter and inside the StoredProcedure i run the above Query in question formulating the IN section using the passed parameter .
So all above code still applies, The parameter passed to the storeDProcedure is one String separated by , without the single quotes.
Might not be the optimum answer but works quit well :) .

Categories

Resources