How to convert common format sql to mybatis support sql - sql

Here I need to convert common format sql such as:
select * from table where id = 'abc' limit 1
to mybatis supporting format such as:
select * from table where id = #{id} limit #{count}
so that sql could be executed in mybatis to aviod sql injection attack and complete different DB type convert using mybatis.
The reason why I have to use mybatis do that is because following request:
1 the orignal sql is come from user input, so have to insure the safe of that sql
2 mybatis support different DB, so no need to write code to convert field for different DB type
3 and also mybatis interception function should involved.
I have tried using Druid WallVisitorutils.check() to verify the safty of orignal sql, but I don't think that is a good way to fulfill the 3 requests.
I am considering MyBatis Dynamic SQL, but can't find a good way.
is there any suggestion?

Related

Mulesoft not able to pass dynamic SQL queries based on environments

Hello for demonstration purposes I trimmed out my actual sql query.
I have a SQL query
SELECT *
FROM dbdev.training.courses
where dbdev is my DEV database table name. When I migrate to TEST env, I want my query to dynamically change to
SELECT *
FROM dbtest.training.courses
I tried using input parameters like {env: p('db_name')} and using in the query as
SELECT * FROM :env.training.courses
or
SELECT * FROM (:env).training.courses
but none of them worked. I don't want my SQL query in properties file.
Can you please suggest a way to write my SQL query dynamically based on environment?
The only alternative way is to deploy separate jars for different environments with different code.
You can set the value of the property to a variable and then use the variable with string interpolation.
Warning: creating dynamic SQL queries using any kind of string manipulation may expose your application to SQL injection security vulnerabilities.
Example:
#['SELECT * FROM $(vars.database default "dbtest").training.courses']
Actually, you can do a completely dynamic or partially dynamic query using the MuleSoft DB connector.
Please see this repo:
https://github.com/TheComputerClassroom/dynamicSQLGETandPATCH
Also, I'm about to post an update that allows joins.
At a high level, this is a "Query Builder" where the code that builds the query is written in DataWeave 2. I'm working on another version that allows joins between entities, too.
If you have questions, feel free to reply.
One way to do it is :
Create a variable before DB Connector:
getTableName - ${env}.training.courses
Write SQL Query :
Select * from $(getTableName);

Is SELECT INTO T-SQL?

I'm working in a project where I have been explicitly required to not use T-SQL syntax. The application we are using supports T-SQL but we are not allowed to use it to avoid potential migration issues.
My question is: is the SELECT ... INTO statement T-SQL or SQL? If it is T-SQL, is there a specific SQL query to copy an existing table into a new one? (I have tried with CREATE TABLE AS .. FROM but it doesn't work).
Sounds like a very basic question but I haven't been able to find the answer anywhere. Thus, in addition to the question above, it would be very helpful to know if there is a guide/dictionary/website that collects only the standard SQL syntax.
Thanks!
I think they recommend you to use ANSI SQL, instead of T-SQL (SQL Server) or PL-SQL (ORACLE). Considering it as common requirement, every database vendor provide their own way of implementing this requirement. When you use ANSI SQL, you will not have migration issues, when you move from one database vendor to another database vendor.
SQL SERVER
SELECT * INTO new_table
FROM existing_table
ORACLE & ANSI-SQL
CREATE TABLE new_table
AS SELECT * FROM existing_table
is SELECT INTO TSQL or SQL?
Neither. The MySQL documentation claims that SELECT INTO is a Sybase extension to standard sql. As such I don't think you can accurately say it's either of these, but you can say that it's neither. It is indeed used in T-SQL, as well as some other database vendor products, to create a table from a query. The SQL standard says that queries with that goal should be formed as CREATE TABLE blah AS SELECT .... Oracle/MySQL, for example, use the standard form though you can see them use SELECT INTO in a different context, to assign data to variables in stored procedures
If you want to avoid use of this non standard syntax when creating and populating a table then you'll have to:
CREATE TABLE blah (column spec to match query output)
INSERT blah (select query here)
But then you run into nuances like "sqlserver calls it datetime/datetime2 but oracle calls it date/timestamp"
And ultimately you'll probably get into a situation where you just can't use one form of sql to do all you want..
I'd imagine most libraries that do data access on multiple underlying databases have mechanisms to use vendor specific terminology where required
From the answers, it appears you might need to specify which SELECT INTO you're talking about. The other answers seem to suggest there exists some kind of SELECT ... INTO <table-name> when there is also a kind of SELECT ... INTO <local-variable-name list>. The latter is used in embedded SQL for making SQL interact with variables of the host language program. I'm not certain but that variant may also be used in the part of the SQL language that deals with procedures written in SQL (the SQL/PSM part of the standard).
A "reference" that covers "only the standard SQL syntax" is, in principle, the ISO standard document itself, only available by purchase from ISO (and yes, it's ISO not ANSI - ANSI does nothing more than rubberstamping the ISO document after removing all the names of non-US contributors). And not the easiest kind of literature. There are "draft" versions floating around on the internet that might deviate from the published final standards. E.g. http://www.wiscorp.com/sql200n.zip. Note that this is a SQL:2008 draft. Current standard version is SQL:2011. And it's several thousands of pages, so I guess that covers your question "Is all the syntax covered in w3schools standard SQL". (Hint : no)

jOOQ MERGE support for PostgreSQL conditional insert

I had understood that jOOQ would simulate SQL MERGE on systems (such as PostgreSQL) that don't support it.
I have a table with a serial (autoincrement) "id" column and a string "uri" column. I want to use numeric IDs instead of URIs in my database, so I have to make sure I have a URI in the ID lookup table. So following the example in the jOOQ manual, I thought this would work:
createDSLContext().mergeInto(tableByName("uris"))
.using(createDSLContext().selectOne())
.on(fieldByName("uri").equal("http://example.com/"))
.whenNotMatchedThenInsert(fieldByName("uri"))
.values("http://example.com/").execute();
This gives me a DataAccessException saying something like:
SQL [merge into "uris" using (select 1) on "uri" = ? when not matched then insert ("uri") values (?)]; ERROR: syntax error at or near "merge"
But then the log says jOOQ goes ahead and tries to execute the query with bind values. But the table is never updated. So I'm guessing the jOOQ doesn't simulate MERGE on PostgreSQL?
So I then try the H2 database syntax:
createDSLContext().mergeInto(tableByName("uris"), fieldByName("uri")).values(uri.toString()).execute();
I get:
The H2-specific MERGE syntax is not supported in dialect : POSTGRES
What!? But the jOOQ documentation says that the H2 syntax "can be fully simulated by jOOQ for all other databases that support the SQL standard." Surely PostgreSQL supports the SQL standard. Does it really mean "...the SQL standard version of MERGE?"
Is there any way to get PostgreSQL support for MERGE via jOOQ, or am I stuck doing the same workarounds I would do anyway?
To be sure if a given SQL feature is supported by jOOQ for your database, please consider the Javadoc's #Support annotation on the relevant DSL method. This is also documented in the manual. In this case, DSLContext.mergeInto(), where you can see that this statement is currently only supported for these SQLDialects:
#Support(value={CUBRID,DB2,HSQLDB,ORACLE,SQLSERVER,SYBASE})
MERGE is a very powerful statement that is not really easy to emulate if your database doesn't natively support it.
"can be fully simulated by jOOQ for all other databases that support the SQL standard." Surely PostgreSQL supports the SQL standard. Does it really mean "...the SQL standard version of MERGE?"
Yes of course, the SQL standard MERGE statement must be supported :-) We'll clarify this in the manual. I have registered issue #3183 for this.
Is there any way to get PostgreSQL support for MERGE via jOOQ, or am I stuck doing the same workarounds I would do anyway?
Right now, unfortunately, we don't have a solution for this in PostgreSQL. Feel free to discuss possible solutions on the jOOQ User Group.
Yes , it can support which database support the merge in SQL stand.
but postgresql unsupport this feature in SQL standard.
Please see
F312 MERGE statement
F313 Enhanced MERGE statement
F314 MERGE statement with DELETE branch
http://www.postgresql.org/docs/9.3/static/unsupported-features-sql-standard.html

performance of parameterised SQL

I have a query like
SELECT *
FROM myTable
WHERE key LIKE 'XYZ'
The value 'XYZ' is entered by users (and may include % and _)
If I construct the query using string concatenation it runs in 10 seconds.
But this is unsafe, and I should use a parameterised query.
So I'm constructing the query using the odbc command object and it's execute method, and passing a parameter.
SELECT *
FROM myTable
WHERE key LIKE ?
Unfortunately the parameterised SQL execute method takes a full minute.
This query is one of many that are part of a drill-down / investigation package, and I've had similar slow downs with all the parameterised queries (compared to string concatenation).
How do I find out where the time is going (and fix it) ?
Here's my guess without further information.
I've had similar problems on SQL Server. In SQL Server when the column on your table is 'varchar' and the parameterised query parameter is 'nvarchar' (or vice versa), this causes SQL Server to ignore an available index because the parameter type doesn't match the index type, which in turn results in a table scan.
It's possible the same thing happens for Sybase. If you can see the generated query you can confirm if there's a type mismatch.
If this is the case, then two solutions would be
explicitly set the type of the parameter to match the column type
change the type of the column to match the parameter type being generated
Mitch had the right suggestion.
I had to change the connection string to use the OLEDB driver, then I could set the options:
Optimize Prepare=None
Select Method=Direct

Can you explain this SQL injection?

The website i worked was recently attempted to be hacked by the following SQL injection script
boys' and 3=8 union
select 1,
concat(0x232425,ifnull(`table_name`,0x30),char(9),ifnull(`table_rows`,0x30), char(9),0x252423),
3,4,5,6,7,8,9
from `information_schema`.`tables`
where table_schema=0x62646B3032 limit 44,1 -- And '8'='8
This injection returned the mysql table name. This was reported by the error reporting system on that website and we managed to fix that part however I am not able to understand what does the above injection mean?
Anyone can explain this?
Penuel
They're using a select from the Information Schema views in mysql server :
http://dev.mysql.com/doc/refman/5.0/en/information-schema.html
They use some clever hacks to rout out simple sql injection prevention techniques.
According to this the MySQL concat()
Returns the string that results from
concatenating the arguments. May have
one or more arguments. If all
arguments are nonbinary strings, the
result is a nonbinary string. If the
arguments include any binary strings,
the result is a binary string. A
numeric argument is converted to its
equivalent binary string form
So 0x232425 is converted to #$% which is simply added to the begining and end of the table_name field. Maybe just to make it easier for them to pull out the Table names later using Regex.
Later on the char(9) is equivalent to a tab as you can see here and is just there to format the output nicer.
The 3,4,5,6,7,8,9 is just there so that the columns match the boys table that they are performing the Union on.
This injection returned the mysql table name.
Do you mean that your website displayed the table name when you gave it this input, or that the query returns that when run from the mysql client? If it showed on your website, then the attacker has the ability to inject much more harmful queries. Check your data.