SQL Update statement to update document file and photo - varbinary (max) - java

I wrote a SQL UPDATE statement to update document file and photo stores as varbinary(max) in the DB. At first I got an error saying
Implicit conversion from data type varchar to varbinary(max) is not allowed. Use the CONVERT function to run this query
So I changed the code and did it like this.
try {
//SET Varbinary_Col = CAST(Varbinary_Content as VARBINARY)
query = "UPDATE tourClient SET DocumentFile= CONVERT(varbinary(max),'"+docFile+"'),Photo= CONVERT(varbinary(max),'"+person_image+"') WHERE Name= '" + combo_client.getSelectedItem() + "' ";
PreparedStatement stm = db.getconn().prepareStatement(query);
int val = stm.executeUpdate();
if (val > 0) {
JOptionPane.showMessageDialog(null, "Uploaded successfully!!!");
rs.next();
}
db.getconn().close();
} catch (Exception e) {
System.out.println(e);
}
After I run the above query in netbeans, i get the Joption message saying uploaded successfully. I have another jframe in netbeans, which has a query that SELECTS all document files, Images and shows it in a jtable. When I click a row in jtable the image is shown in a label and the document is opened but when I try to open it, it says the file is corrupted and for the image it doesnt show the png that I uploaded.
Have I written the statement correctly? Anything I have to change?

Related

How to insert a file into AS400 through SQL statement

I would like to insert a file that hasn't an extension. It is a text file without a .txt extension. This is my code:
public boolean setData(List<String> data) {
SABConnection connection = new SABConnection();
boolean bool = false;
try {
PreparedStatement ps = connection.connectToSAB().prepareStatement("INSERT INTO AS400.ZXMTR03 VALUES (?)");
if (!data.isEmpty()) {
for (String file: data) {
File fi = new File(file);
FileInputStream fis = new FileInputStream(file);
ps.setAsciiStream(1, fis);
int done = ps.executeUpdate();
if (done > 0) {
System.out.println("File: " + fi.getName() + " Inserted successfully");
}else {
System.out.println("Insertion of File: " + fi.getName() + " failed");
}
}
bool = true;
}else {
System.out.println("Le repertoire est vide");
}
}catch (Exception e) {
System.out.println("error caused by: " + e.getMessage());
}
return bool;
}
I keep getting a data truncation error.
ps:
the file ZXMTR03 doesn't have columns.
to insert such thing manually into as400 I write this statement: insert into ZXMTR03 (select * from n.niama/ZXMTR02) it works. When I write insert into ZXMTR03 values ('12345') it works.
I'm using JT400 library.
You can't insert a stream file into a database table like that.
Assuming your text file has EOL indicators, you'd need to split it into rows to insert one row at time; or insert some distinct number of rows at a time using a multi-row insert.
Also you're wrong in thinking ZXMTR03 doesn't have columns, every DB table on the IBM i has at least 1 column.
Alternatively, you could copy, using FTP, SMB, NFS, ect. or even the JT400 AccessIfsFile class, the text file to the Integrated File System (IFS), which supports stream files. And make use of the Copy From Import File (CPYFRMIMPF) command or perhaps the IFS Copy (CPY) command. If on a current version of the OS, you might want to check out the QSYS2_IFS_READ() table functions

HSQLDB not saving updates made through Java

I am trying to add records to a table in an HSQL database through Java.
I have an HSQL database I made through OpenOffice, renamed the .odb file to .zip and extracted the SCRIPT and PROPERTIES files (It has no data in it at the moment) to a folder "\database" in my java project folder.
The table looks like this in the SCRIPT file
CREATE CACHED TABLE PUBLIC."Season"("SeasonID" INTEGER GENERATED BY DEFAULT AS IDENTITY(START WITH 0) NOT NULL PRIMARY KEY,"Year" VARCHAR(50))
All fine so far, the database connects just fine in Java with this code:
public void connect(){
try{
String dbName = "database\\db";
con = DriverManager.getConnection("jdbc:hsqldb:file:" + dbName, // filenames prefix
"sa", // user
""); // pass
}catch (Exception e){
e.printStackTrace();
}
}
I have the following code to insert a record into "Season".
public void addSeason(String year){
int result = 0;
try {
stmt = con.createStatement();
result = stmt.executeUpdate("INSERT INTO \"Season\"(\"Year\") VALUES ('" + year + "')");
con.commit();
stmt.close();
}catch (Exception e) {
e.printStackTrace();
}
System.out.println(result + " rows affected");
}
I have a final function called printTables():
private void printTables(){
try {
stmt = con.createStatement();
ResultSet rs = stmt.executeQuery("SELECT * FROM \"Season\"");
System.out.println("SeasonID\tYear");
while(rs.next()){
System.out.println(rs.getInt("SeasonID") + "\t\t" + rs.getString("Year"));
}
}catch (Exception e) {
e.printStackTrace(System.out);
}
}
Now if I run this sequence of functions:
connect();
printTables();
addSeason("2010");
printTables();
I get this output:
SeasonID Year
1 rows affected
SeasonID Year
0 2010
Now when I close the program and start it again I get exactly the same output. So the change made during the first run hasn't been saved to the database. Is there something I'm missing?
It's caused by write delay params in hsqldb, by default has 500ms delay synch from memory to files.
So problem is solved when it's set to false
statement.execute("SET FILES WRITE DELAY FALSE");
or set as you like based on your app behaviour.
So my workaround is to close the connection after every update, then open a new connection any time I want to do something else.
This is pretty unsatisfactory and i'm sure it will cause problems later on if I want to perform queries mid-update. Also it's a time waster.
If I could find a way to ensure that con.close() was called whenever the program was killed that would be fine...

JTable: display strings with newline characters as multiple lines

I added a JTable in a JFrame using drag and drop in netbeans.
I was able to display the contents of the database but it is not like what i want to display, i want strings with newlines to be display as multiple lines.
i have a code here that query in the sqlite database and then displayed it in the table.
public void Update_table_RFID(JTable x){
try{
String sql = " select RFID as 'RFID Tag', Word, ARF as 'Audio Recording File', "
+ " DateAdded as 'Date Added', TimeAdded as 'Time Added' "
+ " from RFID";
pst = conn.prepareStatement(sql);
rs = pst.executeQuery();
x.setModel(DbUtils.resultSetToTableModel(rs));
}
catch(Exception e){
JOptionPane.showMessageDialog(null,e);
}
}
but the output i got instead is this:
what do i need to do to display the correct output of the query in the table?

mySQL showing null in images field

when I try to insert an image in MySQL database it shows:
Query OK, 1 row affected (0.06 sec)
but when I try to view it in net beans it tells that the field is null.
Also in MySQL when I put the query to display the field it shows null under the image column.
The strangest thing is that it happens only for some images and other images get added to the database and are displayed by the java net beans.
The table creation query is:
create table rto(sno int(2), image longblob);
the query to insert image in table is:
insert into rto values(2, LOAD_FILE('I:\WP_20150925_004.jpg'));
The java code is:
JFileChooser chooser=new JFileChooser();
chooser.showOpenDialog(null);
File f=chooser.getSelectedFile();
String filename=f.getAbsolutePath();
System.out.println(filename);
{
try{ int r= Integer.parseInt(jt2.getText());
Connection con = DriverManager.getConnection("jdbc:mysql://localhost/darshanproject","root","");
Statement st = con.createStatement();
String q = "Insert into rto values("+r+",LOAD_FILE('"+filename+"'));" ;
int rs = st.executeUpdate(q);
if (rs>0)
System.out.println("image inserted");
else
System.out.println("not inserted");
}catch(Exception ex){
System.out.println(ex);
}
}
// TODO add your handling code here:
}
Please help me out.

Append data to a DB2 blob

In my DB2 database, I have a table with a Blob:
CREATE TABLE FILE_STORAGE (
FILE_STORAGE_ID integer,
DATA blob(2147483647),
CONSTRAINT PK_FILE_STORAGE PRIMARY KEY (FILE_STORAGE_ID));
Using the db2jcc JDBC driver (db2jcc4-9.7.jar), I can read and write data in this table without any problems.
Now I need to be able to append data to existing rows, but DB2 gives the cryptic error
Invalid operation: setBinaryStream is not allowed on a locator or a reference. ERRORCODE=-4474, SQLSTATE=null
I use the following code to append my data:
String selectQuery = "SELECT DATA FROM FILE_STORAGE WHERE FILE_STORAGE_ID = ?";
try (PreparedStatement ps = conn.prepareStatement(selectQuery, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_UPDATABLE)) {
ps.setInt(1, fileStorageID);
try (ResultSet rs = ps.executeQuery()) {
if (rs.next()) {
Blob existing = rs.getBlob(1);
try {
// The following line throws the exception:
try (OutputStream output = existing.setBinaryStream(existing.length() + 1)) {
// append the new data to the output:
writeData(output);
} catch (IOException e) {
throw new IllegalStateException("Error writing output stream to blob", e);
}
rs.updateBlob(1, existing);
rs.updateRow();
} finally {
existing.free();
}
} else {
throw new IllegalStateException("No row found for file storage ID: " + fileStorageID);
}
}
}
My code is using the methods as suggested in OutputStream to the BLOB column of a DB2 database table. There also seem to be other people who have the same problem: Update lob columns using lob locator.
As a workaround, I currently read all the existing data into memory, append the new data in memory, and then write the complete data back into the blob. This works, but it's very slow and obviously it will take longer if there's more data in the blob, getting slower with each update.
I do need to use Java to update the data, but apart from switching away from the JVM, I am happy to try any possible alternatives at all, I just need to append the data somehow.
Thanks in advance for any ideas!
If you only need to append data to the end of a BLOB column and don't want to read the entire value into your program, a simple UPDATE statement will be faster and more straightforward.
Your Java program could run something like this via executeUpdate():
UPDATE file_storage SET data = data || BLOB(?) WHERE file_storage_id = ?
The parameter markers for this would be populated by setBlob(1, dataToAppend) and setInt(2, fileStorageID).

Categories