I am currently working with a product which has either a PostgreSQL database or an Oracle database
In this application, there is a getClob() which will return a clob from an oracle database. However this becomes a problem when the application is using a PostgreSQL database, as the getClob() produces errors, but getString() works perfectly
My question is then: will there be any limitations if I use getString() insted of using getClob()? Limitations such as getString can only handle half the data a clob can etc
Any Help would be appriciated :)
Related
I have java application through which I do different operations on MySQL DB. The probleam is that when inserting utf8 String it is not inserted correctly. The charset of DB is utf8 and I have set collation to utf8_unicode_ci. Server connection collation is also utf8_unicode_ci. Furthermore when I insert data from phpMyAdmin it is inserted correctly, but when I do it from Java application using JOOQ - it is not. Example:
Result<ExecutorsRecord> executorsRecord =
context.insertInto(EXECUTORS, EXECUTORS.ID, EXECUTORS.NAME, EXECUTORS.SURNAME, EXECUTORS.REGION, EXECUTORS.PHONE, EXECUTORS.POINTS, EXECUTORS.E_TYPE)
.values(id, name, surname, region, phone, 0, type)
.returning(EXECUTORS.ID)
.fetch();
where name = "Бобр" and surname = "Добр", produces tuple with ???? as a name and ???? as surname. I have checked both strings, they are passed correctly to the method correctly.
As #spencer7593 suggested the problem could be in JDBC connector. So I added into url of connection following: ?characterEncoding=utf8 so that final url was "jdbc:mysql://localhost:3306/mydb?characterEncoding=utf8", where mydb is a name of database. This has sorted out my problem. Also I would like to add the following statement (again by #spencer7593):
When we've got things configured correctly, and things aren't working, our goto suspect is the JDBC driver. To get timezone differences between the JVM and the MySQL database sorted out, to prevent the JDBC driver from "helping" by doing an illogical combination of various operations, we had to add two extra obscurely documented settings to the connection string.
Further reading
In my company we are performing a database migration. For lots of reasons we cannot use a database migration tool, so we had to develop our migration tool to copy from a DB to another all rows contained in some specific tables. We have developed a tool using JDBC of multiple database. At the moment, we are migrating from DB2 to Oracle, with an intermediate step to H2. Same tables ha a Clob column. When we export this column from DB2 to H2 we get no errors or issues, but when we try to copy the Clob from H2 to Oracle using JDBC we get the following exception:
ClassCastException: cannot cast from org.h2.jdbc.JdbcClob to oracle.jdbc.Clob
Is there a way or a procedure to perform this kind of conversion? Something like a ClobCopy utility within different Clob types? Unfortunately we can do this task only using Java and Jdbc, no JPA or DB migration tools due to customer specifications.
This is an example of what I'm trying to do:
public class CopyTable {
public void doCopy(){
Connection h2 = getH2Connection(); //suppose this exists and works
Connection oracle = getOracleConnection(); //suppose this exists and works
String sqlSelect = "select * from tabletoexport";
String sqlInsert = "insert into tabletofill(ID, DATA) values (?,?)";
PreparedStatement select = h2.prepareStatement(sqlSelect);
PreparedStatement insert = oracle.prepareStatement(sqlInsert);
ResultSet rs = select.executeQuery();
while (rs.next()){
insert.setLong(1, rs.getLong("ID"));
insert.setClob(2, rs.getClob("DATA")); //this throws an exception
insert.executeUpdate();
}
}
}
The Clob interface has a getCharacterStream() method which returns a Reader, and the PreparedStatement interface has a setClob() method which takes a Reader. All you need to do to get the copy working is to use these methods.
In other words, replace the line
insert.setClob(2, rs.getClob("DATA")); //this throws an exception
with
insert.setClob(2, rs.getClob("DATA").getCharacterStream());
As for why the import from DB/2 to H2 didn't complain, perhaps the H2 JDBC driver doesn't assume that Clob values passed in to setClob come from H2, but the Oracle JDBC driver does assume that Clobs passed in in the same way are from Oracle. However, the Oracle JDBC can't reasonably make any such assumptions about a Reader, as these could come from anywhere
I am getting below exception, when trying to insert a batch of rows to an existing table
ORA-00942: table or view does not exist
I can confirm that the table exists in db and I can insert data to that table using oracle
sql developer. But when I try to insert rows using preparedstatement in java, its throwing table does not exist error.
Please find the stack trace of error below
java.sql.SQLException: ORA-00942: table or view does not exist
at oracle.jdbc.dbaccess.DBError.throwSqlException(DBError.java:134)
at oracle.jdbc.ttc7.TTIoer.processError(TTIoer.java:289)
at oracle.jdbc.ttc7.Oall7.receive(Oall7.java:573)
at oracle.jdbc.ttc7.TTC7Protocol.doOall7(TTC7Protocol.java:1889)
at oracle.jdbc.ttc7.TTC7Protocol.parseExecuteFetch(TTC7Protocol.java:1093)
at oracle.jdbc.driver.OracleStatement.executeNonQuery(OracleStatement.java:2047)
at oracle.jdbc.driver.OracleStatement.doExecuteOther(OracleStatement.java:1940)
at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout>>(OracleStatement.java:2709)
at oracle.jdbc.driver.OraclePreparedStatement.executeUpdate(OraclePreparedStatement.java:589)
at quotecopy.DbConnection.insertIntoDestinationDb(DbConnection.java:591)
at quotecopy.QuoteCopier.main(QuoteCopier.java:72)
Can anyone suggest the reasons for this error ?
Update : Issue solved
There was no problem with my database connection properties or with my table or view name. The solution to the problem was very strange. One of the columns that I was trying insert was of Clob type. As I had a lot of trouble handling clob data in oracle db before, gave a try by replacing the clob setter with a temporary string setter and the same code executed with out any problems and all the rows were correctly inserted!!!.
ie. peparedstatement.setClob(columnIndex, clob)
was replaced with
peparedstatement.setString(columnIndex, "String")
Why an error table or view does exist error was throws for error in inserting clob data. Could anyone of you please explain ?
Thanks a lot for your answers and comments.
Oracle will also report this error if the table exists, but you don't have any privileges on it. So if you are sure that the table is there, check the grants.
There seems to be some issue with setCLOB() that causes an ORA-00942 under some circumstances when the target table does exist and is correctly privileged. I'm having this exact issue now, I can make the ORA-00942 go away by simply not binding the CLOB into the same table.
I've tried setClob() with a java.sql.Clob and setCLOB() with an oracle.jdbc.CLOB but with the same result.
As you say, if you bind as a string the problem goes away - but this then limits your data size to 4k.
From testing it seems to be triggered when a transaction is open on the session prior to binding the CLOB. I'll feed back when I've solved this...checking Oracle support.
There was no problem with my database connection properties or with my table or view name. The solution to the problem was very strange. One of the columns that I was trying insert was of Clob type. As I had a lot of trouble handling clob data in oracle db before, gave a try by replacing the clob setter with a temporary string setter and the same code executed with out any problems and all the rows were correctly inserted!!!.
ie. peparedstatement.setClob(columnIndex, clob)
was replaced with
peparedstatement.setString(columnIndex, "String")
#unbeli is right. Not having appropriate grants on a table will result in this error. For what it's worth, I recently experienced this. I was experiencing the exact problem that you described, I could execute insert statements through sql developer but would fail when using hibernate. I finally realized that my code was doing more than the obvious insert. Inserting into other tables that did not have appropriate grants. Adjusting grant privileges solved this for me.
Note: Don't have reputation to comment, otherwise this may have been a comment.
We experienced this issue on a BLOB column. Just in case anyone else lands on this question when encountering this error, here is how we resolved the issue:
We started out with this:
preparedStatement.setBlob(parameterIndex, resultSet.getBlob(columnName)); break;
We resolved the issue by changing that line to this:
java.sql.Blob blob = resultSet.getBlob(columnName);
if (blob != null) {
java.io.InputStream blobData = blob.getBinaryStream();
preparedStatement.setBinaryStream(parameterIndex, blobData);
} else {
preparedStatement.setBinaryStream(parameterIndex, null);
}
I found how to solve this problem without using JDBC's setString() method which limits the data to 4K.
What you need to do is to use preparedStatement.setClob(int parameterIndex, Reader reader). At least this is what that worked for me. Thought Oracle drivers converts data to character stream to insert, seems like not. Or something specific causing an error.
Using a characterStream seems to work for me. I am reading tables from one db and writing to another one using jdbc. And i was getting table not found error just like it is mentioned above. So this is how i solved the problem:
case Types.CLOB: //Using a switch statement for all columns, this is for CLOB columns
Clob clobData = resultSet.getClob(columnIndex); // The source db
if (clobData != null) {
preparedStatement.setClob(columnIndex, clobData.getCharacterStream());
} else {
preparedStatement.setClob(columnIndex, clobData);
}
clobData = null;
return;
All good now.
Is your script providing the schema name, or do you rely on the user logged into the database to select the default schema?
It might be that you do not name the schema and that you perform your batch with a system user instead of the schema user resulting in the wrong execution context for a script that would work fine if executed by the user that has the target schema set as default schema. Your best action would be to include the schema name in the insert statements:
INSERT INTO myschema.mytable (mycolums) VALUES ('myvalue')
update: Do you try to bind the table name as bound value in your prepared statement? That won't work.
It works for me:
Clob clob1;
while (rs.next()) {
rs.setString(1, rs.getString("FIELD_1"));
clob1 = rs.getClob("CLOB1");
if (clob1 != null) {
sta.setClob(2, clob1.getCharacterStream());
} else {
sta.setClob(2, clob1);
}
clob1 = null;
sta.setString(3, rs.getString("FIELD_3"));
}
Is it possible that you are doing INSERT for VARCHAR but doing an INSERT then an UPDATE for CLOB?
If so, you'll need to grant UPDATE permissions to the table in addition to INSERT.
See https://stackoverflow.com/a/64352414/1089967
Here I got the solution for the question. The problem is on glass fish if you are using it. When you create JNDI name make sure pool name is correct and pool name is the name of connection pool name that you are created.
I am having difficulty while reading from oracle database using hibernate. The column is of clob type and mapped class property is of String type. The database is Oracle 11G. I have tried to update my driver as suggested by some posts, But it was of no use. The problem is that All other columns(which are not clob) are read properly and the column which is clob is returned null besides it has data. Thanks in advance.
The query is :
select id,about_us,other_details,periodicity,active,createts,updatets from Details where id = ?
This above the HQL query where about_us and other_details are clob type in database. The java entity contains it as type String.
Rahul
I tried many solutions as suggested in different posts, It includes:
1) Updating odbc jar.
2) Using #lob on the porperty in hibernate mapping/entity.
Both of the above solutions did not work for me, Rather I used the hibernate function str(clob_property) to read it, It worked for me and I could get the property read.
Regards
Rahul
Have you tried something like this?
#Lob #Column(name = "long_text")
private String longText;
I want to know how to run FileMaker(FMP pro) database command in java. I have got the connection to database,but not sure how to execute below query.
Get(AccountPrivilegeSetName)
ref:
http://www.filemaker.com/11help/html/func_ref2.32.4.html#1051898
You will need to add a calculation field in FileMaker to return as the result of the JDBC query. This is because you cannot call functions via JDBC, you can only retrieve field values.