Android + Java + SQLite error reading TEXT field - java

When i save this string to a database:
# there is a hole.
when reading it back i get:
# there is a hol
Notice the missing last to characters: e.
if i try to save:
# theres a hole.
I correctly read back the string. Since the error depends on the lenght of the string, i think it might have something to do with unicode... but i am not sure.
Anybody knows what is going on? Here is the code i use to save the string to database:
lQuery = "UPDATE notices SET note='# there is a hole.' where id=3";
SQLiteDatabase mdb = (SQLiteDatabase) DBconn;
try {
mdb.execSQL(lQuery);
} catch (Exception ee) {
DBlasterr = ee.getMessage();
};
And here is how i am retrieving the string:
lQuery = "SELECT * FROM notices where id=3";
try {
SQLiteDatabase mydb = (SQLiteDatabase) DBconn;
rs = mydb.rawQuery(lQuery, null);
rs.moveToFirst();
Log.d("======", "returned: " + rs.getString(rs.getColumnIndex("note")));
} catch (Exception ee) {
DBlasterr = ee.getMessage();
}

Related

Column count doesn't match value count at row 1 [Java]

I'm trying to add music CD information to a DB with an application. When the button is clicked it will write out the information to a WAMP DB. I keep getting an error and I've looked and couldn't find the solution to my problem.
Driver loaded
SQL error during INSERT
java.sql.SQLException: Column count doesn't match value count at row 1
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:946)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:2985)
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1631)
at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:1723)
Those are the errors that I'm getting
#Override
public void actionPerformed(ActionEvent e) { //this runs when the submit button is pressed
String artistName = txtName.getText();
...
String format = "";
if (rdbtnCd.isSelected()) {
format = "CD";
} else if (rdbtnVinyl.isSelected()) {
format = "Vinyl";
}
String query = "INSERT INTO cds VALUES ('" + artistName + "','" + albumTitle + "','" + recordLabel + "','" + genre + "','" + year + "','" + format +"');";
try {
// Connection c = DBClass.getConnection();
Statement stmt = conn.createStatement();
stmt.executeUpdate(query);
JOptionPane.showMessageDialog(this, "Saved");
} catch (SQLException e1) {
System.out.println("SQL error during INSERT");
e1.printStackTrace();
}
Here's my connect as well
private void connect() {
try { //Login details for the DB.
String userName = "root";
String password = "";
String url = "jdbc:mysql://localhost/music";
conn = DriverManager.getConnection(url, userName, password);
} catch (Exception e) { //Error is DB connection is unsuccessful .
JOptionPane.showMessageDialog(null, "Cannot connect to database server");
// System.err.println(e.getMessage());
System.err.println(e.getStackTrace());
}
JOptionPane.showMessageDialog(null, "Database connection established");
}
Any help would be appreciated. Thank you
The error means that you are providing not as much data as the table cds do contain columns. And now the DB engine does not know in which columns to put your data.
To overcome this you must provide the names of the columns you want to fill. Example:
insert into cds(column_name1, column_name2)
values (1, 3)
Look up the table definition and see which columns you want to fill.
And insert means you are inserting a new record. You are not modifying an existing one. Use update for that.

Getting JdbcBatchUpdateException while testing with EmbeddedDatabase H2

I get strange exception trying to test my code using EmbeddedDatabase H2:
java.lang.RuntimeException:
java.lang.RuntimeException: org.h2.jdbc.JdbcBatchUpdateException: Timeout trying to lock table "CO_SCENARIO_1"; SQL statement:
UPDATE CO_SCENARIO_1 SET VALUE = ? WHERE ATTRIBUTE = ? AND MODIFIER = ? [50200-156]
at de.telekom.skses.test.dao.DatabaseFileConverterTest.fromFile(DatabaseFileConverterTest.java:99)
This is part of code I'm trying to test:
case "overriddenVariables.txt": {
try (Scanner sc = new Scanner(bOut.toString())) {
try (Connection con = dataSource.getConnection()) {
String aQuery = "UPDATE $tableName SET VALUE = ? WHERE ATTRIBUTE = ? AND MODIFIER = ?";
String line = "";
if (sc.hasNext()) {
line = sc.nextLine();
}
while (sc.hasNext()) {
if (line.startsWith("+")) {
String setting = line.substring(1);
try (PreparedStatement ps = con.prepareStatement(aQuery.replace("$tableName", setting))) {
while (sc.hasNext() && !(line = sc.nextLine()).startsWith("+")) {
int del1 = line.indexOf(":");
int del2 = line.indexOf(':', del1 + 1);
String attr = line.substring(0, del1);
String modifier = line.substring(del1 + 1, del2);
String value = line.substring(del2 + 1, line.length());
Clob myClob = con.createClob();
myClob.setString(1, value);
ps.setClob(1, myClob);
ps.setString(2, attr);
ps.setString(3, modifier);
ps.addBatch();
}
ps.executeBatch();
}
}
}
} catch (SQLException e) {
logger.error("Error", e);
throw new RuntimeException(e);
}
} catch (Exception ex) {
logger.error("Error", ex);
throw new RuntimeException(ex);
}
break;
}
StackOverflow says that I should set lock timeout, but I didn't find how to set it for EmbeddedDatabase. Also, in previous version I opened new PreparedStatement for each query and new Connection for each PreparedStatement, everything worked well, and I can't understand why it doesn't now. Could you please explain what I have to do to make it work again?
Sorry if something is incorrect, I'm new to Java EE.
As I remember using H2 in embedded mode, it has problems with concurrency. this is probably why you get the timeout for the lock on the table, since the table is still updated from your last batch when you try to execute the next one. When closing connection and preparedStatement every single time the execution time is way shorter, so you won't get the timeout.
Have you tried adding to the DatabaseURL ;MVCC=true as stated in this post? If this won't solve the problem, is it really necessary to use batches for your update?
EDIT: the post i linked before, links to the h2 website where you can find a description on how to change the lock timeout by adding ;LOCK_TIMEOUT=10000 to your databse URL. This would change it to 10 seconds, standard is 1 second

Inserting values to sqlite table results in error: [SQLITE_CONSTRAINT] Abort due to constraint violation (UNIQUE constraint failed: salesman.code)

I have created a fully-functional java app with mysql db. I have to change the mysql db to sqlite db to make the app more portable (no installation required). I'm in the process of converting all my mysql tables and values to sqlite.
I was to create the database and tables and now, I'm populating my salesman table from a .csv file selected by the user through FileChooser. After the user selects .csv file that would populate the salesman table, NetBeans would result to this error:
java.sql.SQLException: [SQLITE_CONSTRAINT] Abort due to constraint violation (UNIQUE constraint failed: salesman.code)
at org.sqlite.core.DB.newSQLException(DB.java:890)
at org.sqlite.core.DB.newSQLException(DB.java:901)
at org.sqlite.core.DB.execute(DB.java:810)
at org.sqlite.core.DB.executeUpdate(DB.java:847)
at org.sqlite.jdbc3.JDBC3PreparedStatement.executeUpdate(JDBC3PreparedStatement.java:86)
After researching for similar problems, it would mean that the values I'm putting in the salesman table are not aligned with the parameters / constraint set with the salesman table. But when I created the table, I did not put any UNIQUE constraint. I made the table using Browser for SQLite and this is the code for creating database and tables:
try {
Class.forName("org.sqlite.JDBC");
conn = DriverManager.getConnection("jdbc:sqlite:sandapp.db");
String createSalesmanQuery = "CREATE TABLE IF NOT EXISTS salesman (\n" +
" code INTEGER PRIMARY KEY\n" +
" NOT NULL,\n" +
" name TEXT NOT NULL\n" +
")\n" +
"WITHOUT ROWID;";
ps = conn.prepareStatement(createSalesmanQuery);
ps.executeUpdate();
String emptySalesmanQuery = "DELETE FROM salesman;"; //empties if there are contents
ps = conn.prepareStatement(emptySalesmanQuery);
ps.executeUpdate();
} catch ( Exception e ) {
System.err.println( e.getClass().getName() + ": " + e.getMessage() );
System.exit(0);
}
The constraint WITHOUT ROWID is there because the attribute code are coming from another database, so there shouldn't be a table id that auto-increments. I already checked the .csv file where all the values for column codes are and there are no repeating values. This file was also used for mysql db and it uploaded successfully. Anyone have any ideas?
EDIT: Here is my method that gets the salesman details from a .csv file
public static String getSalesmanFromFile(String filePath){
ArrayList<Salesman> salesmanList= new ArrayList<Salesman>();
String status = null;
try {
BufferedReader br = new BufferedReader(new FileReader(filePath));
String line = null;
String[] strSalesman = null;
try {
Class.forName("org.sqlite.JDBC");
Connection connection = DBConnection.getConnection();
PreparedStatement ps = null;
while ((line=br.readLine()) != null){
strSalesman = line.split(",");
salesmanList.add(new Salesman(Integer.parseInt(strSalesman[0]), strSalesman[1]));
String insertSalesmanQuery = "INSERT INTO salesman VALUES(?, ?);";
ps = connection.prepareStatement(insertSalesmanQuery);
for(int i = 0; i<salesmanList.size(); i++){
ps.setInt(1, salesmanList.get(i).getCode());
ps.setString(2, salesmanList.get(i).getName());
ps.executeUpdate();
}
status = "Successfully uploaded";
}
ps.close();
} catch (IOException ex) {
ex.printStackTrace();
} catch (SQLException ex) {
ex.printStackTrace();
} catch (ClassNotFoundException ex) {
ex.printStackTrace();
} finally {
try {
br.close();
} catch (IOException ex) {
ex.printStackTrace();
}
}
} catch (FileNotFoundException ex) {
ex.printStackTrace();
status = "Error"; //- Please review file selected. Make sure that format is followed.";
System.out.println(status);
}
return status;
Here are sample Salesman details from .csv file:
5099 JONATHAN REYES
5010 EDWIN DAVID
These two values return the error stated above in the Output log in NetBeans.

Update to MySQL returns 1, no errors/exception, but no updates actually take place

The below method is supposed to update MySql DB with the company info passed to it.
I have other methods that insert and delete and work fine, however this method runs without exceptions, and always returns 1.
The general_log file shows that it received the update string but there are still no changes.
The only time I can get it to work is if I run the code in the MySql workplace directly.
If you need more info to figure this out, please let me know.
I gave you all I thought was needed.
Thanks.
// SQL update string received from the program in the log file
// UPDATE couponsprojectdb.company SET Email = 'admin#MyCompany.org', Password = 'pass' WHERE ID = 3
public void updateCompanyById(Company c, long id) throws SQLException
{
Connection conn = pool.getConnection(); // Gets an available connection from pool
// Prepared statement string
String sql = ("UPDATE company SET Email = ?, Password = ? WHERE ID = ?");
PreparedStatement p = conn.prepareStatement(sql);
p.setString(1, c.getEmail());
p.setString(2, c.getPassword());
p.setLong(3, id);
int i = p.executeUpdate();
System.out.println("changes: " + i);
pool.releaseConnection(conn);
}
You never called conn.commit() after doing the executeUpdate(). The reason the Java code returns 1 is because it succeeded, but the database rolled back the UPDATE immediately after the transaction ended.
You also need to close your connections. Change your code to this:
try {
Connection conn = pool.getConnection();
String sql = ("UPDATE company SET Email = ?, Password = ? WHERE ID = ?");
PreparedStatement p = conn.prepareStatement(sql);
p.setString(1, c.getEmail());
p.setString(2, c.getPassword());
p.setLong(3, id);
int i = p.executeUpdate();
conn.commit(); // <-- MAKE SURE TO COMMIT THE TRANSACTION TO THE DATABASE!!!
System.out.println("changes: " + i);
pool.releaseConnection(conn);
} catch(Exception e) {
// handle errors here
} finally {
try { if (p != null) p.close(); } catch (Exception e) {};
try { if (conn != null) pool.releaseConnection(conn); } catch (Exception e) {};
}
Big hat tip to this SO post which got me thinking about your problem.

How to use setCharacterStream to update Clob in Oracle?

When I used the follow snippets to update Oracle Clob:
String toBeUpdated = ""
StringReader reader = new StringReader(toBeUpdated);
pStmt.setCharacterStream(parameterIndex,reader , toBeUpdated.length());
When the length of string "toBeUpdated" is a little bit bigger(general more than 5000) and a value had been ready stored into db, it was without any exceptions and the expected value was returned in method executeUpdate() when I ran the above codes. but the stranger probelm is that I checked DB and found the column was null.(it should be updated with new value).
it did not happened every time but a little bit randomly.
I tried use pStmt.setString() instead of pStmt.setCharacterStream everything was going to be fine. as far as I know setString is limited of maximize string size(63000) it cannot be proposed solution.
Is anybody can light me or experienced this?
Oracle provide Classes for store CLOB from strings. I have use the following code and it works fine:
long id = ...
String content = ... // CLOB content
try {
Class.forName ("oracle.jdbc.OracleDriver");
Connection conn = DriverManager.getConnection("jdbc:oracle:thin:#MY_SERVER:1521:MY_DB", "user", "pass");
String query = "UPDATE MY_TABLE SET MY_CLOB_COLUMN = ? WHERE ID = ? ";
OraclePreparedStatement opstmt = (OraclePreparedStatement)conn.prepareStatement(query);
opstmt.setStringForClob(1, content);
opstmt.setLong(2, id);
int result = opstmt.executeUpdate();
System.out.println("Resultado para : " + tabla + " - " + columna + " - " + id + ":" + result);
} catch (SQLException ex) {
//Log here
} catch (ClassNotFoundException ex) {
//Log here
}

Categories

Resources