Spring NamedParameterJdbcTemplate: get the resulting SQL query with parameters substituted - sql

I need to get the final SQL query that is sent to the database from NamedParameterJdbcTemplate.
For example:
SELECT * FROM tbl WHERE name = :name;
I need something like this:
SELECT * FROM tbl WHERE name ='mark';
Thanks a lot.

A quick look at the source code of the NamedParameterJdbcTemplate will show that all the queries get through getParsedSql() method and the NamedParameterUtils for parsing.
SELECT * FROM tbl WHERE name = :name;
Will probably get translated to something like
SELECT * FROM tbl WHERE name = ?;
And the parameter will be provided as a separate object, because that's how JDBC works.
If you just want to inspect the statements you can add some breakpoints and take a look. If you want to actually obtain the values you can change the code, to make it accessible, either by reflection or by actually using your own version of NamedparameterJdbcTemplate.
Note that you won't probably see what you expect.

Related

Ordering output of LIST in Snowflake

I've been using the LIST command to check the files staged to a table in Snowflake. However, the data is unordered and I'd like to order it by last_modified. I tried embedding it into a SELECT query like this:
SELECT *
FROM LIST #MY_DATABASE.MY_SCHEMA.%my_table/path/to/data PATTERN = '.*[.]csv.*'
However, this query fails to compile. I've tried preceding LIST with the CALL keyword as well, but no luck there. I've even tried assigning it to a local variable, but that doesn't work either. The data appears to be tabular so I'm not sure why I can't work with it.
How can I query on the output of LIST?
I am personally using the following "hacky" solution:
Start by executing the "list" command.
I Then use the result_scan function combined with last_query_id function to fetch the results of that query, as this point I can start querying the data, here's how it looks:
LIST #MY_DATABASE.MY_SCHEMA.%my_table/path/to/data PATTERN = '.*[.]csv.*'
WITH data(name, size, md5, last_modified) as (
SELECT * FROM table(result_scan(last_query_id()))
)
select *
from data
order by last_modified desc;
Obviously this is a manual hack as I retrieve the last query id, if you can't ensure this property you need to get the actual query id and use that explicitly instead.

SQL query using CONTAINS doesn't work on specify keyword

I am writing a simple query in SQL Server:
SELECT *
FROM Table1
WHERE CONTAINS(Column1, 'MY')
but it doesn't return any results. While using like it returns results.
Is there any specific reason why the keyword 'MY' doesn't work?
Update:
If I use other keywords, it works, only the specific 'MY' seems to be that I cannot used. My column is already set into fulltext index. Also for performance purposes I prefer to use CONTAINS.
you could do something like
select * from Table1 where Column1 like '%MY%'
When you use linq you can use the statements like you use in C#. It will be translated to SQL, a language which database can execute. So, try something like this:
string sql = "SELECT * FROM Table1 WHERE Column1 like #Column1";
And in your command, try to add parameters to replace the #Column1
command.Parameters.AddWithValue("#Column1", "%MY%");
The % char, represents anything. So, if you want to do a command like StartWith like we do from string, just use MY%.

Delete Query inside Where clause

Is there any possibility to write delete query inside Where clause.
Example:
Select ID,Name From MyTable Where ID IN(Delete From MyTable)
It may be crazy, but let me explain my situation. In our reporting tool, we are supporting to enter SQL where query.
We will use our own Select and From Clause query and combine the user's where query input.
Example:
Select ID,Name From MyTable Where ("Query typed by user")
Here, user can type any kind of where query filter..
If he types like ID=100 our final query becomes like this
Select ID,Name From MyTable Where (ID=100)
One of our customer asked us what will happen if anyone type the delete query as where query filter. he feels this may be the security hole..so we have tried that kind of possibility in our dev environment. But the sql returns error for the following query.
Select ID,Name From MyTable Where ID IN(Delete From MyTable)
So finally, my question is, is there any other possibility to write Delete Query inside Where clause or Select clause.. If it possible, how can I restrict it?
Yes. They can run a delete. They can type:
1 = 1; DELETE FROM MY_TABLE;
Or even worse in some ways, (since you should have backups):
1 = 0 UNION SELECT SOCIAL_SECURITY_NUMBER, CREDIT_CARD_NUMBER, OTHER_SENSITIVE_DATA FROM MY_SENSITIVE_TABLE;
Now, in your case its hard to validate. Normally if you are just passing a value to filter on you can use parameterised sql to save yourself. You however also need to let the user select a column. In cases like these, usually we use a drop down to allow the user to select a predefined list of columns and then validate the column name server side. We give the user a text box to enter the value to match and then parameterise that.
It's not quite possible. But he can do something like this :
Select ID,Name From MyTable Where (ID=100); (DELETE FROM MyTable Where 1 = 1)
by using ID=100); (DELETE FROM MyTable Where 1 = 1 instead of ID=100
I believe what your customer is talking about is SQL injection, as long as you have taken appropriate methods to block other queries from running after your select statement is done, then you should have no problem in letting them type whatever it is that you want.
From my experience there is no way to delete anything when you are doing a select statement.
Just make sure you have query terminator characters so they don't write something like the following.
select column1,column2, from myTable where ID in (1,2); delete from my table
this would be a valid worry from your customer if you aren't taking proper steps to prevent sql injection from happening.
You could have your SQL reporting tool just not have update, or delete permission and just have it have Read permission. However, it is up to you guys have you handle your sql injection security.

NHibernate, accessing data from a stored procedure that has multiple result sets

I have working code that looks something like this:
var query = CreateSqlQuery("exec spMyStoredProcedure");
query.SetResultTransformer(Transformers.AliasToBean(typeof(MyMappedObjectDTO)));
return query.List<MyMappedObjectDTO>();
With my stored procedure looking something like this:
SELECT * FROM #myTable1
This works fine. However, I want to (in my stored procedure) add another data set by putting in an additional select statement so that my SP would look something like this:
SELECT * FROM #myTable1
SELECT * FROM #myTable2
However, when I run my code, it only returns the data from the first select statement. How can I access both data sets with the resulting ISQLQuery??
Thanks in advance!
It's not possible. NHibernate will use only the first result set.

How to find all records that share the same field value as some other record?

I need to extract all records which have a field which does NOT have a unique value.
I can't figure out an elegant way to do it - using annotation or some other way. I see a "value_annotate" method to the object manager but it's unclear if it's at all related.
Currently I'm using the inelegant way of simple looping through all values and doing a get on the value, and if there's an exception it means it's not unique..
Thanks
I can't say much about the Django part, but the query would look something like:
SELECT *
FROM foo
WHERE id IN (
SELECT MAX(id)
FROM foo
GROUP BY bar
HAVING COUNT(*)=1)
This will return all records where the "bar" field is unique.
I'd go direct to a raw query in this case. This'll look something like the following, assuming you're using Django 1.2:
query = """
SELECT *
FROM table
GROUP BY field
HAVING COUNT(*) > 1
"""
non_uniques = Table.objects.raw(query)
For earlier than 1.2, see the django docs on raw queries