Generate sql statements with flyway placeholders - java

I trying to save some sql insert statements to files to use them for testing.
I would like to use flyway placeholders for that but I'm not able to find any.
Some example in Java:
var sqlTXT = sql.insertInto(table("TBLNAME"))
.set(field("strCol"), field("strVal").toString())
.set(field("placeHolderCol"), field(inline("${flyway:user}")))
.getSQL(ParamType.INLINED);
This will produce SQL string like this one:
insert into TBLNAME (strCol, placeHolderCol) values ('strVal', '${flyway:user}')
and I'm looking for something like this
insert into TBLNAME (strCol, placeHolderCol) values ('strVal', ${flyway:user})
So flyway can substitute ${flyway:user} and insert user name.
Is there any way to render sql like this or will I have to do it "manually"?

Flyway's placeholders are no different from any other "vendor specific" SQL syntax, which isn't supported out of the box by jOOQ, so plain SQL templating has the answer.
Just use
field("${flyway:user}")
Don't use DSL.inline(), which is used for creating "inline values" (e.g. a string literal).

Related

Is SQL Injection possible in the below query

So I'm reviewing some code and Fortify marked the following query as SQL Injectible
"select"+seqName+".NEXTVAL from DUAL;"
Yes, absolutely. It is basically the archetypical example for SQL Injection vulnerability.
If seqName is something like " * from User_passwords; --" the select will query whatever table is used in seqName.
Of course this might not apply if seqName is from a secure source, like some hardcoded list inside the program for example.
To avoid the SQL injection, you'd need to assert the value of the string before concatenating it into the statement, which you can do using one of the dbms_assert subprograms, e.g. DBMS_ASSERT.SQL_OBJECT_NAME

Java PreparedStatement Cross-DB with casting

I have a PreparedStatement intended to be run both on ORACLE and on MYSQL.
But I cannot figure out how to handle the CAST(NULL AS ...)
On Oracle the following works (but not on Mysql):
SELECT TIMB_INS,
CAST(NULL AS TIMESTAMP) AS TIMB_CLO
FROM TOPS
On Mysql the following works (but not on Oracle):
SELECT TIMB_INS,
CAST(NULL AS DATETIME) AS TIMB_CLO
FROM TOPS
(Please note that the first column selected, "TIMB_INS", returns the correct data type for target database type in both cases, i.e. TIMESTAMP for Oracle and DATETIME for MySql.)
There is a way to put it so that it works for both?
I.E. Can i make it db-indipendent in some way?
Thanks
Marco
Based on the tags I can see you're calling this statement from some java code. There are several ways doing so:
Use the DAO pattern. I.e. for each SQL flavor provide a java file that contains the SQL-s.
Use an ORM like Hibernate or JPA. That will take care of this kind of differences.
As a quick hack, you can edit the SQL manually, like in the snippet below. But then you have to determine somehow if the underlying database is Oracle or MySQL
String SQL_PATTERN = "... CAST(NULL AS %s) AS TIMB_CLO ...";
String SQL = String.format(SQL_PATTERN, isOracle ? "TIMESTAMP" : "DATETIME");

Sqlserver: what are the differences between execute sql with jdbc driver and execute with sql client

I have a table named "T_ROLE", it has just one column named "NAME" which type is nvarchar(255), the sqlserver Collation is "SQL_Latin1_General_CP1_CI_AS"(en_US), now i want to insert japanese character, so i know that i need do sql like this:
INSERT INTO T_ROLE(NAME) VALUES(N'japaneseString')
this can be successful.
if i do sql:
INSERT INTO T_ROLE(NAME) VALUES('japaneseString')
which without N prefix, it will saved as '?', i can under these behavior.
But when i use sqlserver jdbc driver to do insert operation like this:
String sql = "INSERT INTO T_ROLE (NAME) VALUES(?)";
stmt.setString(1, "");
stmt.execute(sql);
notice: i don't use stmt.setNString() method, but it can be saved successful, why?
See this blog: https://blogs.msdn.microsoft.com/sqlcat/2010/04/05/character-data-type-conversion-when-using-sql-server-jdbc-drivers/
It turns out that the JDBC driver sends character data including varchar() as nvarchar() by default. The reason is to minimize client side conversion from Java’s native string type, which is Unicode.
So how do you force the JDBC driver not to behave this way? There is a connection string property, named sendStringParametersAsUnicode. By default it’s true.
One would ask what if I want to pass both varchar and nvarchar parameters at the same time? Well, even with the connection property set false, you can explicitly specify nvarchar type like this:
pStmt.setObject(2,Id,Types.NVARCHAR); //Java app code
Simple Google search for sql server jdbc nvarchar found this answer.

SQL Query works in workbench but gives syntax error in java

I ran the query in both sql Workbench and in the executeUpdate() method in java:
in Workbench:
INSERT INTO recentsearches (name) VALUES ("blah");
in java:
statement.executeUpdate("INSERT INTO recentsearches (name) VALUES (\""+name+"\""));
Assuming name = "blah". But I get a syntax error from running the query in java, I've already checked the string value for name. It definitely comes up as "blah", and I didn't forget the speech marks around string values, yet I still get a syntax error.
The error I get in my console is:
check the manual that corresponds to your MySQL server version for the
right syntax to use near '' at line 1
Try to use:
"INSERT INTO recentsearches (name) VALUES("+name+")";
My advice, use PreparedStatement because it has:
-Precompilation and DB-side caching of the SQL statement leads to overall faster execution and the ability to reuse the same SQL statement in batches.
-Automatic prevention of SQL injection attacks by builtin escaping of quotes and other special characters. Note that this requires that you use any of the PreparedStatement setXxx() methods to set the values

Executing a sql server query containing clause " where col like N'myStr%' " from java using spring

my query works using sql server management studio. However I can not get the query to work with named parameters and springsJDBCTemplate.
So actual sql required that works fine :
select colA from table1 where colb like N'lem%'
and a snippet of what I have tried :
String paramA = "N'lem%'";
select colA from table1 where colb like :paramA
I am using springs namedParamterJDBCTemplate. The N specifies nvarchar and unicode encoding as the actual parameters are encoded in foreign languages, eg cyrillic.
N' is useful when presenting some text to the textual SQL parser in SSMS, but when you are using parameterised queries through spring, DON'T! The string itself should be in Unicode, and the framework with handle it for you by declaring the parameter as NVarchar as well as marshalling the param properly.
String paramA = "lem%";
I don't believe you should even have the single quotes in the string, which I understand you're including only because of the N' notation.
You might want to try escape sequence for
String paramA = "N\'lem%'";
http://docs.oracle.com/javase/tutorial/java/data/characters.html

Categories