Mule 4 - Set Start Date & End Date as QueryParams - stored-procedures

I'm having trouble defining both start and end dates as a query parameters. When the data gets pulled, it needs to return as a range of dates based on the query parameters. The GET URL would look like http://localhost:8081/test?FileType=Sales&StartDate=2022-10-01&EndDate=2022-10-26. This should return a date range of data from 10/1/2022-10/26/2022.
In my query, my where clause is set to:
where dp.Nid = 405 and fs.DDate=:DDate
**dp and fs are used in my joins and 405 is an ID that i'll need to unique identify a product.
My input Parameters:
{ DDate : attributes.queryParams.StartDate, DDate : attributes.queryParams.EndDate }
What do i need to set to make a range of dates? Do i need to set startdate to > and enddate to < ? Also, is it possible to define query parameters when using a stored procedure instead of select database method in anypoint studio?

Operations in Mule 4 (ie the boxes inside a flow) can have several inputs (payload, variables, attributes) and 1 output, but they are expected to be independent from each other. The Database query operation doesn't care if its inputs come the query params or from somewhere else. You need to map inputs explicitly to parameters in the query.
Once you have the arguments you need to use them in the SQL query. Usually that means adding a greater than and a lesser than comparison, to ensure that the value is in range. Or the same including also equals, if the business logic requires it.
Depending on the data types and the SQL dialect you may need to convert the inputs to a date format that is compatible with the database type of the column. The inputs here are strings, because that's what query params always are parsed to. The column type is something that you will need to understand and see how to transform, in DataWeave or in the SQL query.
As an example:
<db:select config-ref="dbConfig">
<db:sql>SELECT ... WHERE dp.Nid = 405 AND fs.DDate >= :StartDate AND fs.DDate <= :StartDate</db:sql>
<db:input-parameters>
#[{
StartDate : attributes.queryParams.StartDate,
EndDate : attributes.queryParams.EndDate
}]
</db:input-parameters>
</db:select>

Related

Where comparison on join table with buffer value on rails

How can I use the join table's column value with arithmetic operation during the where condition on Rails?
User and Order are the two Schema, Order has user via Foreign key relation
My goal is to find if an Order was created/placed within 5 minutes of User creation (Understanding Users who signup for placing an Order)
Tried the following queries
Order.where('country': 'US').joins(:user).where('orders.created_at <= :u_date', {u_date: 'users.created_at' + 5.minutes })
With this query we get the following error no implicit conversion of Time into String, so the users.created_at is not evaluating into a Date
Hence tried converting the string to DateTime objects, which failed too
Order.joins(:user).where('orders.created_at < ?', 'users.created_at'+ 5.minutes)
How can I do the comparison inside the Where query?
Right now I am plucking the data and comparing it, It'd be great to make it work inside the Where or any relevant query itself
You're invoking + on a string passing as argument a Time object, which is not an out-of-the-box operation, at least in Rails.
If the time to add is not dynamic you could try;
where("orders.created_at <= users.created_at + INTERVAL '5.minutes'")
which makes your DBMS add the proper interval to users.created_at (in this case I'm assuming Postgresql)

Passing params to sql query

So, in my rails app I developed a search filter where I am using sliders. For example, I want to show orders where the price is between min value and max value which comes from the slider in params. I have column in my db called "price" and params[:priceMin], params[:priceMax]. So I can't write something kinda MyModel.where(params).... You may say, that I should do something like MyModel.where('price >= ? AND price <= ?', params[:priceMin], params[:priceMax]) but there is a problem: the number of search criteria depends on user desire, so I don't know the size of params hash that passes to query. Are there any ways to solve this problem?
UPDATE
I've already done it this way
def query_senders
query = ""
if params.has_key?(:place_from)
query += query_and(query) + "place_from='#{params[:place_from]}'"
end
if params.has_key?(:expected_price_min) and params.has_key?(:expected_price_max)
query += query_and(query) + "price >= '#{params[:expected_price_min]}' AND price <= '#{params[:expected_price_max]}'"
end...
but according to ruby guides (http://guides.rubyonrails.org/active_record_querying.html) this approach is bad because of SQL injection danger.
You can get the size of params hash by doing params.count. By the way you described it, it still seems that you will know what parameters can be passed by the user. So just check whether they're present, and split the query accordingly.
Edited:
def query_string
return = {}
if params[:whatever].present?
return.merge({whatever: #{params[:whatever]}}"
elsif ...
end
The above would form a hash for all of the exact values you're searching for, avoiding SQL injection. Then for such filters as prices you can just check whether the values are in correct format (numbers only) and only perform if so.

Gorm count elements group by day without time

I wish to retrieve a list of UserProfile registrations per day.
The domain object UserProfile stores a Date creationDate property.
I've tried
def results = UserProfile.executeQuery('select u.creationDate, count(u) from UserProfile as u group by u.creationDate')
println results
which obviously is not what I need because data is (already) stored with complete time in it.
Any resource savvy solution will fit: projections, hql, ...
Thnks
I use HQL cast function:
def results = UserProfile.executeQuery("""
select cast(u.creationDate as date), count(u)
from UserProfile as u
group by cast(u.creationDate as date)
""")
Underlying database must support ANSI cast(... as ...) syntax for this to work, which is the case for PostgreSQL, MySQL, Oracle, SQL Server and many other DBMSs
Break down the date to day, month and year then ignore the timestamp.
This should give you what you need.
def query =
"""
select new map(day(u.creationDate) as day,
month(u.creationDate) as month,
year(u.creationDate) as year,
count(u) as count)
from UserProfile as u
group by day(u.creationDate),
month(u.creationDate),
year(u.creationDate)
"""
//If you do not worry about dates any more then this should be enough
def results = UserProfile.executeQuery( query )
//Or create date string which can be parsed later
def refinedresults =
results.collect { [ "$it.year-$it.month-$it.day" : it.count ] }
//Or parse it right here
def refinedresults =
results.collect {
[ Date.parse( 'yyyy-MM-dd', "$it.year-$it.month-$it.day" ) : it.count ]
}
You could define a "derived" property mapped as a formula to extract the date part of the date-and-time. The exact formula will differ depending what DB you're using, for MySQL you could use something like
Date creationDay // not sure exactly what type this needs to be, it may need
// to be java.sql.Date instead of java.util.Date
static mapping = {
creationDay formula: 'DATE(creation_date)'
}
(the formula uses DB column names rather than GORM property names). Now you can group by creationDay instead of by creationDate and it should do what you need.
Or instead of a "date" you could use separate fields for year, month and day as suggested in the other answer, and I think those functions are valid in H2 as well as MySQL.

how to compare string with sql date in grails

I have written query like this
Rule.findAll("FROM Rule WHERE client_id = ? " +
"AND DATE_FORMAT(contract_begins,'%d-%m-%Y') <= ?", [tripStartDate])
But it is not able to compare the sql date with string tripStartDate, how to solve this problem ,how to check contract_begins is less than or equal to tripStartDate.
The easiest way would be to construct a new data object from your string to pass into the query. Assuming (I may be misunderstanding) contract_begins is mapped as a date type in your Rule
Date tripStart = new SimpleDateFormat("dd-MM-yyyy").parse(tripStartDate)
Rule.findAllByClientAndContractBeginsLessThanEquals(client, tripStart)
or if you really want to keep the hql rather than dynamic finder
Date tripStart = new SimpleDateFormat("dd-MM-yyyy").parse(tripStartDate)
Rule.findAll("FROM Rule WHERE client_id = :clientId AND contract_begins <= :tripStart",
[clientId: client.id, tripStart: tripStart])

Erlang ODBC parameter query with null parameters

Is it possible to pass null values to parameter queries? For example
Sql = "insert into TableX values (?,?)".
Params = [{sql_integer, [Val1]}, {sql_float, [Val2]}].
% Val2 may be a float, or it may be the atom, undefined
odbc:param_query(OdbcRef, Sql, Params).
Now, of course odbc:param_query/3 is going to complain if Val2 is undefined when trying to match to a sql_float, but my question is... Is it possible to use a parameterized query, such as:
Sql = "insert into TableY values (?,?,?,?,?,?,?,?,?)".
with any null parameters? I have a use case where I am dumping a large number of real-time data into a database by either inserting or updating. Some of the tables I am updating have a dozen or so nullable fields, and I do not have a guarantee that all of the data will be there.
Concatenating a SQL together for each query, checking for null values seems complex, and the wrong way to do it.
Having a parameterized query for each permutation is simply not an option.
Any thoughts or ideas would be fantastic! Thank you!
You can use the atom null to denote a null value. For instance:
Sql = "insert into TableX values (?,?)".
Params = [{sql_integer, [Val1]}, {sql_float, [null]}].

Resources