OutputStream to the BLOB column of a DB2 database table - java

In a DB2 database, I have the following table:
CREATE TABLE MyTestTable
(
MYPATH VARCHAR(512) NOT NULL,
MYDATA BLOB,
CONSTRAINT MYTESTTABLE_PK PRIMARY KEY (MYPATH)
);
Using Java, I wish to update an existing row in this table with new blob data. My preferred way is to obtain an OutputStream to the BLOB column & write my data to the OutputStream.
Here is the test code I am using:
Connection connection = null;
PreparedStatement pStmnt = null;
ResultSet rSet = null;
try {
connection = ... // get db connection
String id = ... // set the MYPATH value
String sql = "SELECT MYDATA FROM MyTestTable WHERE MYPATH='"+id+"' FOR UPDATE";
pStmnt = connection.prepareStatement(sql);
rSet = pStmnt.executeQuery();
while (rSet.next()) {
Blob blobData = rSet.getBlob("MYDATA"); // this is a java.sql.Blob
OutputStream blobOutputStream = blobData.setBinaryStream(1);
blobOutputStream.write(data);
blobOutputStream.close();
connection.commit();
}
}
// close ResultSet/PreparedStatement/etc in the finally block
The above code works for the Oracle DB.
However, in DB2, calling setBinaryStream to get the OutputStream does not seem to work. The data does not get updated, and I do not get any error messages.
Qs: How can I get an OutputStream to the BLOB column of a DB2 table? What might need to be changed in the above code?

You are probably getting the data written to the Blob object successfully, but you need to do more with the PreparedStatement and ResultSet in order to actually update the value in the database.
First, your PreparedStatement must be instantiated using a version of Connection.prepareStatement() that takes a resultSetConcurrency parameter, which you must set to the value ResultSet.CONCUR_UPDATABLE. (I don't know that the SQL SELECT actually needs to specify the FOR UPDATE clause - see the tutorial at the link at the end of this answer.)
Second, after you close blobOutputStream, you need to update the value in the ResultSet using updateBlob(int columnIndex, Blob x) or updateBlob(String columnLabel, Blob x), then invoke ResultSet.updateRow() before doing a Connection.commit().
I haven't updated Blob values this way myself, but it should work. If you run into any issues trying to reuse the Blob originally read from the ResultSet (which you probably don't need to do if you're not actually using the original data), you can use Connect.createBlob() to make an empty one to start with. You can learn more about updating ResultSets from this tutorial.

Related

Is there an function to retrieve the binary XML from oracle result set

I am trying to extract the data from XMLTYPE COLUMN "ATTRIBUTE_XML2" STORE AS SECUREFILE BINARY XML from an Oracle 12C database.
I am using this select query in my code:
select xmlserialize(document a.xmlrecord as clob) as xmlrecord from tablename
ResultSet rset = stmt.executeQuery();
OracleResultSet orset = (OracleResultSet) rset;
while (orset.next()) {
oracle.sql.CLOB xmlrecord = (oracle.sql.CLOB) orset.getClob(1);
Reader reader = new BufferedReader(xmlrecord.getCharacterStream());
}
Here "orset.getClob" is taking more memory in oracle DB and we are getting out of process memory in the oracle database. Currently we have the XML type storage as CLOB and business is interested to change it to BINARY XML.
Is there any option for retrieving the binary XML from the oracle result set?
Please note that i have tried "orset.getClob" which results in memory error, since it is changing the binary XML to clob.
Also tried with " XMLType xml = (XMLType) orset.getObject(1);" this is working fine, but it is taking 27 minutes for fetching 1 million XML records.
Whereas the same 1 million completed in 5 minutes if the table type storage is CLOB instead of BINARY XML.
Is there any other option for retrieving the BINARY XML ?
The Oracle documentation for Using JDBC to Access XML Documents in Oracle XML DB states that:
You can select XMLType data using JDBC in any of these ways:
Use SQL/XML function XMLSerialize in SQL, and obtain the result as an oracle.sql.CLOB, java.lang.String or oracle.sql.BLOB in Java. The Java snippet in Example 13-2 illustrates this.
Call method getObject() in the PreparedStatement to obtain the whole XMLType instance. The return value of this method is of type oracle.xdb.XMLType. Then you can use Java functions on class XMLType to access the data. Example 13-3 shows how to do this.
So you should be able to use XMLSERIALIZE( DOCUMENT your_binary_xml_column AS BLOB ) in SQL and then use OracleResultSet#getBLOB(int) to get the binary data.
Paraphrasing Oracle's Example 13-2 to cast to a BLOB instead of a CLOB:
DriverManager.registerDriver(new oracle.jdbc.driver.OracleDriver());
Connection conn = DriverManager.getConnection("jdbc:oracle:oci8:#", "QUINE", "CURRY");
OraclePreparedStatement stmt = (OraclePreparedStatement) conn.prepareStatement(
"SELECT XMLSerialize(DOCUMENT e.poDoc AS BLOB) poDoc FROM po_xml_tab e");
ResultSet rset = stmt.executeQuery();
OracleResultSet orset = (OracleResultSet) rset;
while(orset.next())
{
// the first argument is a BLOB
oracle.sql.BLOB clb = orset.getBLOB(1);
// now use the BLOB inside the program
}

ORA-00942: table or view does not exist error on writing to a table in database

I am trying to read a data from one database table using java + jdbc and trying to insert into another database table on different server in same session.
I have created 2 connection object(con,conn1), each pointing to correct database.
With 1st con object i am able to read the data but When it is going to write the data to another table using conn1 it is failing with error
ORA-00942- table or view doesnt exist.
I have also cross-checked that table is present and we can write to that table.
with a standalone class and static data i was able to write to that table.
Please let me know what is wrong in my approach.
Code sample:
public static void main
Class.forName("oracle.jdbc.driver.OracleDriver");
Connection con = DriverManager.getConnection( "URL","uname","passwd");
//code to read from db and add to arraylist.
close resultset, con.
This connection obj points to new a database and url
Connection con1 = DriverManager.getConnection( "url","uname","passwd");
PreparedStatement pstmt = con1.prepareStatement("insert into SCHEMA_NAME.TABLE_NAME(columns) values(?,?,?,?,?,?,?,?)");
//code to iterate the arraylist populated above
pstmt.setint etc
pstmt.executeUpdate();
It fails after executeUpdate statement.
Yes, problem was with pstmt.setClob field. I changed it to pstmt.setString and took .toString() of clob object and it worked.
I m still puzzled why it throws table or view doesnt exist error.

Dump H2 insert statements

Hi How can I dump data only for an instance of H2 In Memory DB.
What I currently have
PreparedStatement preparedStatement = connection
.prepareStatement("SCRIPT SIMPLE NOSETTINGS");
ResultSet resultSet = preparedStatement.executeQuery();
response.setContentType("text/plain");
ServletOutputStream out = response.getOutputStream();
while (resultSet.next()) {
String columnValue = resultSet.getString(1);
out.print(columnValue);
out.println();
This dumps the entire db structure however not just the insert data. Basically what I want to do is backup the data I insert during development mode so the next time the database is started I can script the data back in.
The table structure isn't a problem as it is done by JPA.
To filter out just inserts, you could use:
if (columnValue.startsWith("INSERT")) {
out.println(columnValue);
}

the issue about the ResultSet.TYPE_SCROLL_INSENSITIVE

my database is oracle ,the oracle charset is "us7ascii".and i save chinese charset in the database ,normally ,i get the data from the database ,use
Statement s =conn.createStatement();
then execute the sql, then use
new String (string.getBytes("iso-8859-1"),"gbk")
i can get the correct data.but if i use:
Statement s = conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
still use:
new String (string.getBytes("iso-8859-1"),"gbk")
convert the encode,but i can't get the correct data ,the result is "?????" ,why ?

Using Java (HTMLUnit) to Scrape a Web Page then Write Results to a mySQL Database

I've been able to use Java and HTMLUnit to scrape a web page, however I'm unsure how I can get this to write the resulting data to a MySQL database on a remote hosted server. I also need this to happen at regular intervals (perhaps once a day) if possible, without having to manually run the program.
Is this possible and can I have any guidance, thorough or not, on how to do this?
Thanks!
Get your page's HTML into some String variable
String scrapedHtml = "";
Create a table in mysql with a text field
create table html_store (
id int primary key autoincrement,
content text not null
);
Use JDBC code to connect to the database and inset the data. Set the connectionURL and other parameters correctly
Connection conn = DriverManager.getConnection(connectionURL, user, password);
PreparedStatement pstmt =
conn.prepareStatement("insert into html_store (content) values (?)");
pstmt.setString(1, scrapedHtml);
pstmt.executeUpdate();
pstmt.close();
conn.close();

Categories

Resources