I have a Postgresql database and I want to truncate some tables using JDBC. How do I do that?
This is what I tried, but none worked... without even any error being reported:
Using CallableStatement.
try (Connection connection = getConnection();
CallableStatement statement = connection.prepareCall("TRUNCATE " + tableName)) {
return statement.execute();
}
Using Statement.
try (Connection connection = getConnection();
Statement statement = connection.createStatement()) {
return statement.execute("TRUNCATE " + tableName);
}
Using PreparedStatement.
try (Connection connection = getConnection();
PreparedStatement statement = connection.prepareStatement("TRUNCATE " + tableName)) {
return statement.execute();
}
After the truncate, I need to commit:
try (Connection connection = getConnection();
Statement statement = connection.createStatement()) {
int result = statement.executeUpdate("TRUNCATE " + tableName);
connection.commit();
return result;
}
From the documentation:
TRUNCATE is transaction-safe with respect to the data in the tables: the truncation will be safely rolled back if the surrounding transaction does not commit.
You may run into issues if the table has dependencies. If so, truncate the parent tables first, and also use the CASCADE option.
Connection connection = getConnection();
try {
PreparedStatement statement = connection.prepareStatement("TRUNCATE " + parentTable1, parentTable2, ... + " CASCADE");
try {
return statement.execute();
} finally {
statement.close();
}
} finally {
connection.close();
}
First, if you are truncating a table, you probably want to also RESTART IDENTITY (in addition to possibly doing CASCADE, as John Hogan mentioned).
Second, as far as doing a connection.commit(), the assumption is that you have autocommit set to OFF. My Postgres was set up with it set to ON (apparently, that is sometimes the default).
If it is set to ON, then calling the commit is unnecessary, and will result in the error:
"org.postgresql.util.PSQLException: Cannot commit when autoCommit is enabled."
Third, you may not have permission to truncate a table (or restart identity). In that case, you will need to:
DELETE from your_table
SELECT setval('your_table_id', 1)
The following worked for me:
public String truncateTable(String tableName, boolean cascadeFlag) {
String message = "";
try {
connection = DriverManager.getConnection(url, username, password);
Statement statement = connection.createStatement();
String truncation = "TRUNCATE TABLE yourSchema." + tableName + " RESTART IDENTITY" + (cascadeFlag ? " CASCADE" : "");
System.out.println("truncateTable: Executing query '" + truncation + "'.");
int result = statement.executeUpdate(truncation);
// connection.commit(); // If autocommit is enabled (which it is for our DB), then throws exception after truncating the table.
statement.close();
connection.close();
} catch (SQLException sqlex) {
message = "Could not truncate table " + tableName + ". " + sqlex.getMessage();
System.err.println(message);
sqlex.printStackTrace();
}
return message;
}
Also:
public int deleteResetTable(String tableName, String fieldName) {
int affectedRows = 0;
try {
connection = DriverManager.getConnection(url, username, password);
String sql = "DELETE FROM yourSchema." + tableName;
PreparedStatement preparedStatement = connection.prepareStatement(sql);
affectedRows = preparedStatement.executeUpdate();
System.out.println("Deleted " + affectedRows+ " rows from table " + tableName + ".");
sql = "SELECT setval('yourSchema." + fieldName + "', 1)";
preparedStatement = connection.prepareStatement(sql);
affectedRows = preparedStatement.executeUpdate();
System.out.println("Reset " + affectedRows+ " values from table " + tableName + ".");
} catch (SQLException ex) {
System.out.println("Failed to delete rows from " + tableName + " " + ex.getMessage());
}
return affectedRows;
}
Related
I am currently working on a program the function of which is to store my passwords, and this is why I am using an SQL database called Users. This database contains tables for all the users which will be using the program. Those tables have four columns:
SiteName, Username, Password, AdditionalInfo
I am having a problem updating a specific row. This is my the code I get an error with:
public static void editPassword(String user, String siteEdited, String site, String usernamej, String password, String info){
try{
System.out.println(usernamej);
Class.forName("org.sqlite.JDBC");
c = DriverManager.getConnection("jdbc:sqlite:res/Users");
c.setAutoCommit(false);
stmt = c.createStatement();
String update = "UPDATE " + user + " set Username = " + usernamej + " where SiteName = " + siteEdited;
stmt.executeUpdate(update);
stmt.close();
c.close();
}catch(Exception e){
System.err.print( e.getClass().getName() + ": " + e.getMessage());
}
}
It is in a class made specifically for dealing with the sql database and it gets the following error when I try to change the username to 'test':
java.sql.SQLException: [SQLITE_ERROR] SQL error or missing database (no such column: test)
Assuming the value you pass in for user is the name of the table, your update string is going to look like
UPDATE usertable SET Username = test where SiteName = siteEditedValue
You need to quote the string values:
UPDATE usertable SET Username = 'test' where SiteName = 'siteEditedValue'
The quick and dirty way is:
String update = "UPDATE " + user + " set Username = '" + usernamej + "' where SiteName = '" + siteEdited + "'";
However, it's much (much, much) better to use a PreparedStatement in this case:
public static void editPassword(String user, String siteEdited, String site, String usernamej, String password, String info){
try{
System.out.println(usernamej);
Class.forName("org.sqlite.JDBC");
c = DriverManager.getConnection("jdbc:sqlite:res/Users");
stmt = c.prepareStatement("UPDATE " + user + " SET Username = ? Where SiteName = ?");
stmt.setString(1, usernamej);
stmt.setString(2, siteEdited);
stmt.executeUpdate();
stmt.close();
c.close();
}catch(Exception e){
System.err.print( e.getClass().getName() + ": " + e.getMessage());
}
}
This code assumes the type of stmt is PreparedStatement, not just Statement.
As well as taking care of quoting the values for you, this will escape any sql for you, preventing the possibility of SQL-injection attacks (while these are far less of an issue in a desktop application that a web application, it's still a good habit to get into).
#griFlo I got it running with this code:
public static void editPassword(String user, String siteEdited, String site, String usernamej, String password, String info){
try{
System.out.println(usernamej);
Class.forName("org.sqlite.JDBC");
c = DriverManager.getConnection("jdbc:sqlite:res/Users");
c.setAutoCommit(false);
PreparedStatement stmt = c.prepareStatement("UPDATE " + user + " SET Username = ? Where SiteName = ?");
stmt.setString(1, usernamej);
stmt.setString(2, siteEdited);
stmt.executeUpdate(update);
c.commit();
stmt.close();
c.close();
}catch(Exception e){
System.err.print( e.getClass().getName() + ": " + e.getMessage());
}
}
I had forgotten to put c.commit();
I have problem with my SQL request, when I run my request, I receive this message error:
org.postgresql.util.PSQLException: A result was returned when none was expected.
Here is my request:
Connexion con = new Connexion();
try {
c = con.Connect();
stmt = c.createStatement();
int sqlCalcul = stmt.executeUpdate(
"SELECT inventaire FROM calcul WHERE designation='" + designation +
"' AND date=(SELECT MAX(date) FROM calcul)");
stmt.close();
// c.commit();
c.close();
} catch (Exception e) {
System.err.println(e.getClass().getName() + ": " + e.getMessage());
System.exit(0);
}
System.out.println("Records created successfully");
You should use executeQuery instead of executeUpdate:
ResultSet sqlCalcul = stmt.executeQuery("SELECT inventaire...")
executeUpdate is used for a INSERT, UPDATE, or DELETE statement, and will throw an exception if a ResultSet is returned. executeQuery should be used for SELECT statements.
Take a look at PostgreSQL's tutorial using the JDBC driver for more information.
I am trying to update a table using Java JDBC. The method I am using does not throw any errors but the table is not updating. The create table method is below:
public static void Table()
{
Connection c = null;
Statement stmt = null;
try {
Class.forName("org.sqlite.JDBC");
c = DriverManager.getConnection("jdbc:sqlite:WalkerTechCars.db");
System.out.println("Opened database successfully");
stmt = c.createStatement();
String sql = "CREATE TABLE IF NOT EXISTS CUSTOMERS2 " +
"(PHONE TEXT PRIMARY KEY NOT NULL," +
" SURNAME TEXT NOT NULL, " +
" FIRSTNAME TEXT NOT NULL, " +
" HOME TEXT, " +
" ADDRESS TEXT, " +
" POSTCODE Text)";
stmt.executeUpdate(sql);
stmt.close();
c.close();
} catch ( Exception e ) {
System.err.println( e.getClass().getName() + ": " + e.getMessage() );
System.exit(0);
}
System.out.println("Customers2 created successfully");
}
The update method is below:
public static void updateCustomers()
{
Connection c = null;
PreparedStatement pstmt = null;
try {
Class.forName("org.sqlite.JDBC");
c = DriverManager.getConnection("jdbc:sqlite:WalkerTechCars.db");
c.setAutoCommit(false);
System.out.println("Opened database successfully");
String query = "UPDATE CUSTOMERS2 set ADDRESS = ? where PHONE = ? ";
pstmt = c.prepareStatement(query); // create a statement
pstmt.setString(1, "1"); // set input parameter 1
pstmt.setString(2, "DOES THIS WORK"); // set input parameter 2
pstmt.executeUpdate(); // execute update statement
pstmt.close();
c.close();
} catch ( Exception e ) {
System.err.println( e.getClass().getName() + ": " + e.getMessage() );
System.exit(0);
}
System.out.println("Update Completed successfully HELLO");
}
I have tried to find some clear instructions on this but cant find any. I do not really understand JDBC and prepared statement very well
When autoCommit is false (c.setAutoCommit(false);), you must manually commit the transaction...
Add...
c.commit()
After pstmt.executeUpdate();
You code also has a flaw, in that if some kind of error occurs during the preparation or execution of the statement, both the Connection and PreparedStatement could be left open, causing a resource leak
If you're using Java 7+ you can use the try-with-resources feature, for example...
try {
Class.forName("org.sqlite.JDBC");
try (Connection c = DriverManager.getConnection("jdbc:sqlite:WalkerTechCars.db")) {
c.setAutoCommit(false);
System.out.println("Opened database successfully");
String query = "UPDATE CUSTOMERS2 set ADDRESS = ? where PHONE = ? ";
try (PreparedStatement pstmt = c.prepareStatement(query)) {
pstmt.setString(1, "1"); // set input parameter 1
pstmt.setString(2, "DOES THIS WORK"); // set input parameter 2
pstmt.executeUpdate(); // execute update statement
c.commit();
}
} catch (SQLException exp) {
exp.printStackTrace();
}
} catch (ClassNotFoundException exp) {
exp.printStackTrace();
System.out.println("Failed to load driver");
}
This will ensure that regardless of how you leave the try block the resource will be closed.
You might also consider taking a look at the JDBC(TM) Database Access
Your update method will set ADDRESS to 1 if there is any row in table with PHONE = does this work.
Try to put Address in 1st Input parameter and Phone 2nd Input parameter
When a connection is created, it is in auto-commit mode.
We need to use [setAutoCommit] method only when we need to make Auto Commit false and make it manual commit after executing the query.
More details at Oracle site on JDBC Transaction.
I'm trying to check if the "Username" and "Email" arguments in my constructor are existed in the SQL Table.
this is my code:
public DB(String usr, String eml, String pwd) {
this.usr = usr;
this.eml = eml;
this.pwd = pwd;
String jdbcUrl = "jdbc:mysql://localhost:3306/registered";
String jdbcUser = "....";
String jdbcPassword = "....";
try {
Class.forName("com.mysql.jdbc.Driver");
connection = DriverManager.getConnection(jdbcUrl, jdbcUser,
jdbcPassword);
statement = connection.createStatement();
now , if i use SELECT with two columns, like this:
String command = "SELECT UserName,Email FROM users WHERE UserName LIKE '" + this.usr.toString() + "';";
resultSet = statement.executeQuery(command);
and then do my loop for resultSet... like this:
while (resultSet.next()) {
if (usr.equalsIgnoreCase(resultSet.getString("UserName"))) {
System.out.println("UserName : " + this.usr + " is taken!");
}
else if (eml.equalsIgnoreCase(resultSet.getString("Email"))) {
System.out.println("Email : " + this.eml + " is taken!");
}
else {
System.out.println("Email : " + this.eml + " and UserName : " + this.usr + " are AVAILABLE!");
command = "INSERT users SET UserName = '" + this.usr.toString() + "',Email = '" + this.eml.toString() + "',Password = '" + this.pwd.toString() + "',Status = '0' ,Connected = '1';";
statement.executeUpdate(command);
}
}
} catch (SQLException e) {
System.out.println("SQLException: " + e.getMessage());
System.out.println("Vendor error: " + e.getErrorCode());
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
the
resultSet.next()
only runs over the "FIRST" column which means
if the "usr" exists in the table it works,
but if the "usr" does not exist in the table, the other two if statements does-not work ..
,... i want to check both first column and second,.. and maybe third or more soon.. , any help?
Your WHERE clause only tests for the UserName, so if the UserName doesn't match this.usr.toString(), the resultSet will be empty, so the while loop won't be entered.
You should change the query to match all the fields you care about - something like - "SELECT UserName,Email FROM users WHERE UserName = ... OR Email = ..."
If the resultSet is empty, you'll know that you can insert the new record. Otherwise, you can check which of the fields (UserName, Email) is already taken.
One more thing you should be aware of - executing a SQL statement without PreparedStatement makes your code vulnerable to SQL injection attacks.
You should change your code to something like this :
PreparedStatement pstmt = con.prepareStatement("SELECT UserName,Email FROM users WHERE UserName = ? OR Email = ?");
pstmt.setString(1, this.usr);
pstmt.setString(2, this.eml);
resultSet = pstmt.executeQuery();
You should change your INSERT statement similarly to use PreparedStatement.
I have a system in which there are hundreds of table. So i am getting values from them by making sql query in a loop. But if any table does not exists it quits further execution.
Can i place a condition if any table does not exists then it search for next table....
You can use this. This will return list of tables, iterate though it and see if table exist.
DatabaseMetaData meta = con.getMetaData();
ResultSet res = meta.getTables(null, null, null,
new String[] {"TABLE"});
while (res.next()) {
System.out.println(
" "+res.getString("TABLE_CAT")
+ ", "+res.getString("TABLE_SCHEM")
+ ", "+res.getString("TABLE_NAME")
+ ", "+res.getString("TABLE_TYPE")
+ ", "+res.getString("REMARKS"));
}
You could just catch the exception:
List<String> tableNames = ...;
Statement stmt = ...;
ResultSet rs = null;
for (String tableName : tableNames) {
String sql = buildQuery(tableName);
try {
rs = s.executeQuery(sql);
useData(rs);
} catch {
log.error ("could not execute query on " + tableName);
} finally {
if (rs != null) {
rs.close();
}
}
}