How can I execute this sql backup script with JDBC? - java

How can I execute the following query against my database instance using JDBC, Everything I am trying is returning "no result set" errors.
com.microsoft.sqlserver.jdbc.SQLServerException: The statement did not return a result set.
What do I do when I'm not really looking data back as such?
.sql file
DECLARE #name VARCHAR(50) -- database name
DECLARE #path VARCHAR(256) -- path for backup files
DECLARE #fileName VARCHAR(256) -- filename for backup
DECLARE #fileDate VARCHAR(20) -- used for file name
DECLARE #fileFolder VARCHAR(20) -- used for file name
-- specify database backup directory
SET #path = 'C:\SQLBackups\'
-- specify filename format
SELECT #fileDate = CONVERT(VARCHAR(20),GETDATE(),112)
DECLARE db_cursor CURSOR FOR
SELECT name
FROM master.dbo.sysdatabases
WHERE name NOT IN ('master','model','msdb','tempdb') -- exclude these databases
OPEN db_cursor
FETCH NEXT FROM db_cursor INTO #name
WHILE ##FETCH_STATUS = 0
BEGIN
SET #fileName = #path + #name + '_' + #fileDate + '.BAK'
BACKUP DATABASE #name TO DISK = #fileName
FETCH NEXT FROM db_cursor INTO #name
END
CLOSE db_cursor
DEALLOCATE db_cursor
My code for executing said query (so far)
public static void connect(String instance, String saPassword, String query) {
Connection conn = null;
query = "DECLARE #name VARCHAR(50) -- database name " +
"DECLARE #path VARCHAR(256) -- path for backup files " +
"DECLARE #fileName VARCHAR(256) -- filename for backup " +
"DECLARE #fileDate VARCHAR(20) -- used for file name " +
"-- specify database backup directory " +
"SET #path = 'C:\\SQLBackups\\' " +
"-- specify filename format " +
"SELECT #fileDate = CONVERT(VARCHAR(20),GETDATE(),112) " +
"DECLARE db_cursor CURSOR FOR " +
"SELECT name " +
"FROM master.dbo.sysdatabases " +
"WHERE name NOT IN ('master','model','msdb','tempdb') -- exclude these databases " +
"OPEN db_cursor " +
"FETCH NEXT FROM db_cursor INTO #name " +
"WHILE ##FETCH_STATUS = 0 " +
"BEGIN " +
" SET #fileName = #path + #name + '_' + #fileDate + '.BAK' " +
" BACKUP DATABASE #name TO DISK = #fileName " +
" FETCH NEXT FROM db_cursor INTO #name " +
"END " +
"CLOSE db_cursor " +
"DEALLOCATE db_cursor ";
try {
Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver").newInstance();
String dbURL = "jdbc:sqlserver://10.0.0.0\\"+ instance;
String user = "user";
String pass = saPassword;
conn = DriverManager.getConnection(dbURL, user, pass);
Statement stmt = conn.createStatement();
stmt.executeQuery(query);
} catch (Exception ex) {
ex.printStackTrace();
} finally {
try {
if (conn != null && !conn.isClosed()) {
conn.close();
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
I can execute my query just fine in SSMS, is the conversion of the .sql text into the string causing issues here? I'm not too bothered about a result here as it should be creating a lot of .bak files on the server (which does happen when I execute it via SSMS, I changed around the query with grabbing a simple SELECT resultset which works just fine, so I'm a tad lost now.
overwriting the (query) in the method is just for testing purposes, once I get the .bak files landing on the remote server directory I will tidy it up, credentials masked for obvious reasons.
Thanks

Your code is NOT readable (and therefore hard to maintain) as you are mixing both SQL & Java languages together, so I strongly recommend to use callableStatement, you can look here for a simple example.
In simple terms, you need to move all your SQL code to a procedure in the database and then callableStatement.execute()

In your java code call execute() instead of executeQuery(). The latter supposes that your query needs to return a result set, but the former does not assume that.
So, instead of:
stmt.executeQuery(query);
call:
stmt.execute(query);

Related

SQL statement in Java DAO method is not checking if user exists properly

I have DAO method in Java which looks like this:
private boolean validateUser(String email, String username) throws SQLException {
return stmt.execute(
"SELECT NOT EXISTS" +
"(SELECT id from Math_Hub.Users_Information " +
"WHERE username = '" + username + "' OR email = '" + email + "')");
}
The method returns true even if username already exists in database. Why is that?
I tried to test it by hand and the following SQL statement
SELECT NOT EXISTS
(SELECT id from Math_Hub.Users_Information
WHERE username = 'Eren' OR email = 'erenyeager#gmail.com')
This worked perfectly.
NOT EXISTS always return 1 if no row matches in the where clauses. Either use EXISTS or you can go with select query and later check if anything is received in the resultset( select * or select count(*)).

how to create temp table using jdbc java

I need to create a temp table in order to store some ids which i will process under a later query. I am receiving error
com.microsoft.sqlserver.jdbc.SQLServerException: The statement did not return a result set.
When i execute my query for the creation of #temp table inside my sql. I don't need any resultset from this execution just need to create a temporary table with records. Please guide.
Code for my main query:
String queryTempTable = "SELECT TOP (2) A.Id INTO #temp\n" +
"FROM SALESDM.dbo.FactSales A\n" +
"INNER JOIN SALESDM2.dbo.FactSales B\n" +
"ON A.Id = B.Id\n" +
"AND (\n" +
" A.sysDateModified = B.sysDateModified\n" +
" OR A.Id = B.Id\n" +
" OR A.ModifiedDatetime = B.ModifiedDatetime\n" +
" )";
System.out.println(queryTempTable);
if (conn == null) {
System.out.println("Unable to create Connection");
} else {
Statement stmtTempTable = conn.createStatement();
stmtTempTable.executeQuery(queryTempTable);
}
You should use executeQuery only when you are retrieving data and want a ResultSet.
If you are modifying data, then you should use execute:
stmtTempTable.execute(queryTempTable);
If possible create a view using the given query? This will act as a temporary table. And call the view later based on your requirement.

Unable to insert record in MySql using JAVA

I am new to Java and MYSql in fact using this combination first time and facing real trouble. I want to insert few records in a table but unable to do so. Following are the fields and datatype in the table named tbl_cdr in MySql.
**Field** **Type**
DATEANDTIME datetime NULL
VALUE1 int(50) NULL
VALUE2 varchar(50) NULL
VALUE3 varchar(50) NULL
VALUE4 varchar(50) NULL
VALUE5 varchar(50) NULL
The record I want to insert contains following values
2014-05-19 02:37:18, 405, MGW190514023718eab4, 923016313475, IN, ALERTSC
I am using following query and statements to Insert record in table
sqlQuery = "INSERT INTO tbl_cdr (DATEANDTIME,VALUE1,VALUE2,VALUE3,VALUE4,VALUE5)" + "VALUES ("+ forDateAndTime.format(date) + ", " + columnsList.get(1) + ", " + columnsList.get(2) + ", " + columnsList.get(3) + ", " + columnsList.get(4) + ", " + columnsList.get(5) + ")";
try
{
Statement qryStatement = conn.createStatement();
qryStatement.executeUpdate(sqlQuery);
qryStatement.close();
} catch (SQLException ex)
{
Logger.getLogger(CdrProject.class.getName()).log(Level.SEVERE, null, ex);
}
But when I reach the statement qryStatement.executeUpdate(sqlQuery); exception is thrown as:
MySQLSyntaxErrorException: You have an error in your SQL syntax;
check the manual that corresponds to your MySQL server version for the
right syntax to use near '02:37:18, 405, MGW190514023718eab4,
923016313475, IN, ALERTSC)' at line 1
value2 ,value3 ,value4 and value 5 are varchars so it should be written within ''.
Do like this
sqlQuery = "INSERT INTO tbl_cdr (DATEANDTIME,VALUE1,VALUE2,VALUE3,VALUE4,VALUE5)" + "VALUES ("+ forDateAndTime.format(date) + ", " + columnsList.get(1) + ", '" + columnsList.get(2) + "',' " + columnsList.get(3) + "',' " + columnsList.get(4) + "',' " + columnsList.get(5) + "')";
You're inserting the date incorrectly. MySQL allows you to insert a string literal or a number.
You're trying to use 02:37:18 as a number, when really you should be using it as a string literal: '02:37:18'
Here is the MySql Reference describing this.
You're also not treating your varchars as strings either, they should be enclosed with quotes.

How to Alter table using JOOQ?

Previously I was working with statement but I need to convert it with JOOQ
Statement dboSt = null;
dboSt = dboConn.createStatement();
I need to know how to change my below lines in JOOQ.
dboSt.executeUpdate("alter login \"" + UserId + "\" with password='" + NewPassword + "'");
dboSt.executeUpdate("alter login \"" + UserId + "\" with password='" + NewPassword + "' old_password='" + OldPassword
+ "'");
Is there any solution to convert it?
jOOQ doesn't support typesafe DDL (yet). It's been on the roadmap for a while: #883
In the mean time, you can execute plain SQL statements using jOOQ directly, as such:
DSLContext ctx = DSL.using(configuration);
// As before, manually inlining arguments:
ctx.execute("alter login \""+UserId+"\" with password='"+NewPassword+"'");
// Better, letting jOOQ do the string escaping for you, preventing
// syntax errors and SQL injection vulnerabilities:
ctx.execute("alter login {0} with password = {1}",
DSL.name(UserId), // org.jooq.Name is rendered with quotes in most DBs
DSL.inline(NewPassword) // org.jooq.Param is inlined as a (string) literal
);

Android SQLite created database but table can't be found

So I'm trying to fetch data from one of my database tables, could you please check this out for me and see if you can spot the error?
SQLiteDatabase db = SQLiteDatabase.openDatabase(DB_PATH, null,
SQLiteDatabase.OPEN_READONLY);
Cursor cursor = db.query(TABLE_CLASSES, new String[] { TABLE_C_DAY,
TABLE_C_NAME, TABLE_C_DAY, TABLE_C_LOCATION, TABLE_C_TIMEHR,
TABLE_C_TIMEMIN, TABLE_C_DURATION, TABLE_C_ONETIMEEVENT,
TABLE_C_CTYPE, TABLE_C_OCCURINGWEEK}, TABLE_C_DAY + "=?",
new String[] { String.valueOf(day) }, null, null, null, null);
Okay so DB_PATH is definitely correct. I tried to close the db connection and it works fine so db works fine and exists.
All of the table column names are correct as these were used in onCreate to create the db and that worked fine. I also tried using
db.rawQuery("SELECT * FROM " + TABLE_CLASSES + " WHERE day = ?", new String[] { String.valueOf(day) });
So when I make the query the app stops and I get a Source code not found message in Eclipse. LogCat says that table 'classes' doesn't exist.
I tried the creation code manually and it worked. Here is the code from onCreate(SQLiteDatabase db);
String CREATE_DB_WITH_INIT_VALUES =
"CREATE TABLE %1$s (%4$s TEXT);" +
"INSERT INTO %1$s VALUES('Lecture');" +
"INSERT INTO %1$s VALUES('Lab');" +
"INSERT INTO %1$s VALUES('Tutorial');" +
"INSERT INTO %1$s VALUES('Meeting');" +
"INSERT INTO %1$s VALUES('Examples Class');" +
"CREATE TABLE %2$s (%5$s smallint, %6$s varchar(40), %7$s varchar(10), %8$s smallint, %9$s smallint, %10$s smallint, %11$s boolean, %12$s smallint, %13$s smallint);" +
"INSERT INTO %2$s VALUES(1,'COMP12112 Computation',1.1,9,0,60,'False','Lecture',3);" +
"INSERT INTO %2$s VALUES(1,'COMP16212 Java OOP 2',1.1,11,0,45,'False','Lecture',3);" +
"INSERT INTO %2$s VALUES(1,'COMP18111 Distributed Systems','Unix',13,15,60,'False','Lab',3);" +
"INSERT INTO %2$s VALUES(2,'Tutorial','LF13',15,0,60,'False','Tutorial',3);" +
"INSERT INTO %2$s VALUES(2,'COMP14111 AI','LF31',10,30,60,'False','Lab',3);" +
"CREATE TABLE %3$s (%14$s smallint, %15$s smallint, %16$s TEXT, %17$s date);";
CREATE_DB_WITH_INIT_VALUES = String.format(CREATE_DB_WITH_INIT_VALUES, TABLE_CLASS_TYPES,
TABLE_CLASSES, TABLE_DEADLINES, TABLE_CT_TYPE,
TABLE_C_DAY, TABLE_C_NAME, TABLE_C_LOCATION, TABLE_C_TIMEHR, TABLE_C_TIMEMIN, TABLE_C_DURATION,
TABLE_C_ONETIMEEVENT, TABLE_C_CTYPE, TABLE_C_OCCURINGWEEK,
TABLE_D_TIMEHR, TABLE_D_TIMEMIN, TABLE_D_DTEXT, TABLE_D_DDATE
);
db.execSQL(CREATE_DB_WITH_INIT_VALUES);
This code doesn't crash and all seems fine but then during the query the table can't be found.
Any idea what is wrong?
What you've done is a valid list of SQL statements. The real problem here is that the method execSQL() only allows you the execution of a single sql statement (See documentation here).
If you want to execute multiple statements automatically, I'd write a method that first splits those statements (by the ending semicolon of each one) and then execute each one in a loop, checking for errors in every iteration so that when some sql statement fails, you can throw a SQLException indicating the sql statement that failed. Something like this:
public static void execSQLScript(SQLiteDatabase db, String script) throws SQLException {
String[] statements = script.split(";");
db.beginTransaction();
for(String statement : statements) {
try {
db.execSQL(statement); // Seems like this method already throws a decent exception
}
catch(SQLException e) {
db.endTransaction(); // Rolling back the changes done
throw e;
}
}
db.setTransactionSuccessful(); // Not rolling but commiting changes, since everything went fine.
db.endTransaction();
}
I'm not a SQL expert but I think your trying to do a little too much when creating the tables. I would suggest creating the table and adding any initial data in 2 different steps.
I don't have any initial data in my database but this is what I'm using to create the table:
createTable = "CREATE TABLE " + TABLE_NAME + "(" + COLUMN_ID + " INTEGER PRIMARY KEY," +
COLUMN_ONE + " TEXT," + COLUMN_TWO + " INTEGER," + COLUMN_THREE + " TEXT," +
COLUMN_FOUR + " TEXT," + COLUMN_FIVE + " TEXT)";
db.execSQL(createTable);
Now in your case after creating the table you can then insert the initial data you want. After
db.execSQL(createTable);
use a ContentValues to add the data you need to the database.
contentValues = new ContentValues();
contentValues.putXXX();
// keep adding data
// the insert method will add the data for you.
SQLiteDatabase.insert(TABLE_NAME, null, contentValues);

Categories

Resources