I am trying to use jOOQ to dynamically construct queries. So far it is going really well, but now I stumbled upon a case that I can not seem to express.
This is a simplified version of the query I want to generate:
Select alias.*, otherAlias.aColumn as aAlias
From table as alias
inner join otherTable as otherAlias
on alias.someColumn = otherAlias.someOtherColumn
Where otherAlias.someOtherColumn in (????????)
My problem is that i cannot seem to express the SELECT part how I need it. If I just use:
.select() -> I get select *
.select(alias.fields()) -> I get Select *
.select((alias.fields() :+ field(name(otherAlias, aColumn)).as(aAlias)):_*) -> I get Select otherAlias.aColumn as aAlias
Is there a way to express this with jOOQ?
The rest of the statement seems to work as expected. I am using jOOQ 3.10.7 in Scala and targeting Postgres at the moment and my statement currently looks like this:
sql
.select()
.from(alias)
.innerJoin(otherAlias)
.on(field(name(alias, someColumn)).eq(field(name(otherAlias, someOtherColumn))))
.where(condition)
Thanks a lot.
Update: I found a way to express this that seems to work by falling back to plain SQL. But I am still wondering whether there is a better way to express this. This works as a select:
.select((field(""""Alias".*"""), field(name(otherAlias, aColumn)).as(aAlias)):_*) -> I get Select "Alias".*, otherAlias.aColumn as aAlias
Assuming that you're using jOOQ 3.11 (which added support for unqualified asterisks and qualified asterisks), you can just write
alias.asterisk()
Or even, using jOOQ's scala extensions
alias.*
This is especially powerful when using the code generator.
Related
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);
We have to work with older version of an ERP system (1993).
It has multiple modules. These modules have windows(tabs). Tabs have cols (obviously).
In this tabs the USER can make a "new column" -> it's like a subquery. Query can be used only in parentheses ().
I'm just curious, is it possible to make an injection by user.
e.g.:
--basic query (self join)
(select i.my_col from my_table i where my_pk = i.pk)
--illlustrating
(select replace(i.my_col, 'UPDATE...') from my_table i where my_pk = i.pk)
Is there any way to make the second query workable ? I mean, can the user somehow update columns whit this method ?
How can i test it ?
Dynamic values can be handled for where condition through preparedStatement and setParameter however unfortunately that option is not available for dynamic column selection.
The best thing can be done is to have all possible/applicable column names before you pass to the query.
// check if my_col is possible values else throw the error.
(select replace(i.my_col, 'UPDATE...') from my_table i where my_pk = i.pk)
Avoiding SQL injection is down to the mechanism which turns the user's input into executable statements. The actual example you posted won't run, but I can think of ways it might be possible to hijack the SELECT to run malicious DML. It depends on the framework: given that the underlying software is ancient I suspect it might be extremely vulnerable.
Generally speaking, if you're worried about SQL Injection you should investigate using Oracle's built-in DBMS_ASSERT package to verify your SQL strings. Find out more
I want to make such a query for my Services ActiveRecord in Rails:
SELECT *
FROM "services" AS s
WHERE /* part using 's' alias */
Normally I'd write just Service.where(/* where part */), but I need to set my alias.
I tried to run ActiveRecord::Base.connection.execute(query), but result of that is not recognized as Service.
How can I handle it?
To use a table alias combine the select method with from:
Service.select("s.*").from("services s")
Which generates this SQL:
SELECT s.* FROM services s
And it returns an ActiveRecord::Relation which you can refine as needed.
Fortunately I found solution during writing this question. Service.find_by_sql(query) works well in my case.
I searched a lot around but cannot find the answer:
I have the following SQL query:
select distinct l.id_book from wa2011.tb_lending as l where l.id_user = 1
It's a very simple query but I cannot manage to write it. How can I write this in HQL?
Thanks a lot!
Cheers.
I tested the code with Hibernate 3.3.2 and MS SQL Server and it works fine:
select distinct u.id from User u where u.login='admin'
So I think your HQL code should looks almost the same (just rewrite it from SQL to object model mapped to Hibernate).
I found that Entity SQL support NEWID(), but does ObjectQuery support it as well?
http://msdn.microsoft.com/en-us/library/bb738616.aspx,
Can I write objectquery like:
context.member.orderby("NEWID()").select("it.UserID");
or something like this? or I should write in other way?
I thought if entity sql support NEWID() function, it should be accepted by ObjectQuery also. Like you can use distinct(it.UserID), or BitWiseAND(it.UserID, 1) in ObjectQuery.Where() or Select().
Many thanks.
This is a SQL Server-specific canonical function, so it should be prefixed with 'SqlServer':
context.member.orderby("SqlServer.NEWID()").select("it.UserID");
Unfortunately, this will not work either: the Where extension method needs at least one reference to the immediate input scope.
Thanks Devart for response.
Actually, I found that I can use like:
var query1 = context.member.select("it.userid, SqlServer.NEWID() as newid").orderby("it.newid");
this can make random order for result, you will find that NEWID() is in the translated sql query.
but if you want to select partially result from 'query1' result set, you cannot write:
var query2 = context.member.select("it.userid, SqlServer.NEWID() as newid").orderby("it.newid").select("it.userid");
because when you use sql profiler to watch the sql that translated pass into sql server, you will find that the 'NEWID()' disappear.
However, I think 'query2' should be make sense. But it doesn't work.