How to Alter table using JOOQ? - java

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
);

Related

How can I execute this sql backup script with JDBC?

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);

Error In JDBC Template Querying

I am trying to write this query in order to authenticate the username and password of my API but I am getting error column not found. Both username and passwords are strings and I am using MYSQL database. I think there is a error with quotations as username and password are strings. How can I rectify the below code or is there a better way to write the same.
P.S - I am using spring MVC and this is my first project.
#Override
public TypeInfo getRole(final TypeInfo typeinfo) {
String sql =
"select Role from registartion where UserName=\"" + typeinfo.getUserName() + "and Password=\"" + typeinfo.getPassword() + "/"";
return jdbcTemplate.query(sql, new ResultSetExtractor<TypeInfo>() {
#Override
public TypeInfo extractData(ResultSet rs)
throws SQLException, DataAccessException {
if (rs.next()) {
System.out.println("VALID USER");
TypeInfo typeinfo1 = new TypeInfo();
typeinfo1.setUserName(typeinfo.getUserName());
typeinfo1.setPassword(typeinfo.getPassword());
typeinfo1.setRole(rs.getString("Role"));
return typeinfo1;
}
System.out.println("Not A valid user");
return null;
}
});
}
I am getting a error that "select Role from registartion where UserName=******" column name ******* not found.
That's not the way you should write your query.
JdbcTemplate uses an Object[] array as parameters, to avoid SQL injection.
code it somewhere in the lines of this:
String user = "yourUser";
String password = "yourPassword";
final String sql = "SELECT * from FOO where username = ? and password = ?";
Object[] sqlParameters = new Object[]{user, password};
List<YourEntityClass> list = getJdbcTemplate.query(sql, new BeanPropertyRowMapper<Your Entity Class>(YourEntityClass.class), sqlParameters);
BeanPropertyRowMapper actually maps the values for you. just make sure your entity class has the same property names as the ones on your database
more info here:
jdbcTemplate examples
The proper solution would be to use a PreparedStatement, in order to avoid having to mess with quoting and enhance security.
If you really must construct the statement by string concatination, you should note that string literals in SQL are denoted by single quotes ('), not double quotes ("):
String sql =
"select Role from registartion where UserName='" + typeinfo.getUserName() + "' and Password='" + typeinfo.getPassword() + '";
Try this.
String sql = "select Role from registartion where UserName='" + typeinfo.getUserName() + "' and Password='" + typeinfo.getPassword() + "'";
Change the double quotes (including the escape characters) to single quotes.
Close the single quote enclosing the user name (typeinfo.getUserName()). You need to keep a space between the closing single quote and the subsequent string.
If it still does not work then check the table names and column names. Maybe it is 'registration' and not 'registartion'? Or may be it is 'user_name' and not 'username'?
Tips for beginners: Copy paste the sql string into any database browser, replace the variables with actual values and execute. Check for any errors. It is easier to fix errors this way.
And lastly, use parameterized sql queries to avoid sql injection. In my opinion parameterized queries reduces syntax errors too.
You have to use single qoutes around the column values:
"select Role from registartion where UserName='" + typeinfo.getUserName() + "' and Password='" + typeinfo.getPassword() + "'";
You should better use PreparedStatement. It is easier to read and safer (prevents sql injection).

How to insert DATE using jsp

I have a feedback page on my site that contains name, email and comments. Here is my code on JSP and I'm using Apache Tomcat 7.0 and Oracle DB
String query = "Insert into t_comments(name, email, comments) values('"
+ realname
+ "','"
+ email
+ "','"
+ comments+"')";
This works great. But I decided to add DATEC column (data type DATE) to my table t_comments. So my query should look like
String query = "Insert into t_comments(name, email, comments,datec) values('"
+ realname
+ "','"
+ email
+ "','"
+ comments
+ "',"
+ "TO_DATE('"
+ new java.util.Date()
+ "', 'dd/mm/yyyy hh24:mi:ss'))";
And this doesn't work.
ORA-01858: a non-numeric character was found where a numeric was expected
Maybe I insert wrongly type DATE into my table. Also I have another problem. The name and comments are in Cyrillic. And when they inserted in table, they are displayed incorrect with different encoding. I have this lines in my JSP page
<%# page language='java' contentType='text/html; charset=UTF-8' pageEncoding='UTF-8'%>
So help me please solve my two problems
insert DATE to my table
insert Cyrillic words correct to my table
Thanks
Let oracle do it for you instead.
String query = "Insert into t_comments(name, email, comments,datec) values('"
+ realname
+ "','"
+ email
+ "','"
+ comments
+ "', CURRENT_TIMESTAMP)";
See this link for more info.
You should debug your code and check if a Date object toString() matches the pattern expected by Oracle.
Potentially, if you don't want to go in Arvind's way (which I think it's a good idea actually), you can format your Date using SimpleDateFormat.
You should also consider using a PreparedStatement instead of building the statement using String concatenation.
I thank all for your answers. I'm using CURRENT_TIMESTAMP to insert DATE to my table from #Arvind Sridharan and for cyrillic characters I added the following lines in my jsp
request.setCharacterEncoding("UTF-8");
realname = new String(realname.getBytes("ISO-8859-1"),"UTF8");
comments = new String(comments.getBytes("ISO-8859-1"),"UTF8");

Insert into database a scraped page containing double quotes with MySQL and Java

Imagine my page has a bunch of sections looking something like this (example page):
<div class="content">
</div>
My goal is to scrape the entire page into a MySQL DB entry. I currently do this like so:
//Declare SQL statement
String sql = "INSERT into rns " +
"(rns_pub_date, rns_headline, rns_link, rns_fulltext, constituent_id) values (\""+
rns.getRnsPubDate() + "\",\"" +
rns.getRnsHeadline() + "\",\"" +
rns.getRnsLink() + "\",\"" +
rns.getRnsFullText() + "\",\"" +
"(select constituent_id from constituent where constituent_name = " + rns.getRnsConstituentName() + "\")";
//SQL Statement Debug
Log.d(CLASS_NAME, "createRns. sqlStatement: " + sql);
//Initialize insertValues
insertValues = connect.prepareStatement(sql);
However, this falls over because there are multiple " marks in the page.
I can see a few options:
Escape the characters like this: '\"'
Replace the characters with: '"'
Remove all non-relevant data (the HTML) and save only the relevant data to the DB
I realise that there's also best practice with regards to preventing SQL injection. However this is a standalone system, so for the moment isn't an issue. Having said that if any answer can explain how to prevent that, I would prefer to implement that instead.
Edit 1:
Following on from #chrylis comment. This is what I have:
//Insert values into variables
String rns_pub_date = rns.getRnsPubDate();
String rns_headline = rns.getRnsHeadline();
String rns_link = rns.getRnsLink();
String rns_fulltext = rns.getRnsFullText();
String rns_constituent_name = rns.getRnsConstituentName();
//Prepare the SQL string
String sql = "INSERT into rns (rns_pub_date, rns_headline, rns_link, rns_fulltext,constituent_id) VALUES" + "(?,?,?,?,(select constituent_id from constituent where constituent_name = \"" + rns.getRnsConstituentName() + "\")";
//Prepare the statement
PreparedStatement prest = connect.prepareStatement(sql);
prest.setString(1, rns_pub_date);
prest.setString(2, rns_headline);
prest.setString(3, rns_link);
prest.setString(4, rns_fulltext);
prest.setString(5, rns_constituent_name);
However it provides this error:
Parameter index out of range (5 > number of parameters, which is 4).
Edit 2:
The insert was fixed by removing the escaped double quotes for the 5th parameter:
String sql = "INSERT into rns (rns_pub_date, rns_headline, rns_link, rns_fulltext, constituent_id) VALUES" + "(?,?,?,?,(select constituent_id from constituent where constituent_name = ?))";
Use PreparedStatement, there will be no need for escaping. Usage example is in API
It's not only a bad practice because of SQL injection, it's slow and inefficient, too, and has problems with quote characters. Use a parameterized query.

Escaping a single quote when using JdbcTemplate

We're using JdbcTemplate to modify our underlying Oracle database. We're doing this by way of the update(String sql) method.
The code looks somehow like the following:
String name = "My name's yellow";
String sql = "update FIELD set NAME = '" + name "' where ID = 10
jdbcTemplate.update(sql);
This causes the error:
java.sql.SQLException: ORA-00933: SQL command not properly ended
The problem is the unescaped ' in the name variable.
What's the most convenient and correct way to escape this character?
Use PreparedStatement. That way you nominate a placeholder and the JDBC driver will perform this correctly by sending the database the statement, plus the parameters as arguments.
String updateStatement =
"update " + dbName + ".COFFEES " +
"set TOTAL = TOTAL + ? " +
"where COF_NAME = ?";
PreparedStatement updateTotal = con.prepareStatement(updateStatement);
updateTotal.setInt(1, e.getValue().intValue());
updateTotal.setString(2, e.getKey());
The question marks in the above represent the placeholders.
Because these values get passed as parameters, you don't have problems with quoting, and it protects you against SQL injection too.
Try for name :
if ( name.contains("'") ){
name.replaceAll("'", "''");
}

Categories

Resources