how to compare string with sql date in grails - 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])

Related

Mule 4 - Set Start Date & End Date as QueryParams

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>

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 get data out of a recordset in excel?

I have the following code:
Dim cn As Object
Dim rs As Object
Dim strSql As String
Dim strConnection As String
Dim AppPath As String
Set cn = CreateObject("ADODB.Connection")
AppPath = Application.ActiveWorkbook.Path
Set rs = CreateObject("ADODB.RecordSet")
strConnection = "Provider=Microsoft.ACE.OLEDB.12.0;" & _
"Data Source=" & AppPath & "\Masterlist_Current_copy.accdb;"
strSql = "SELECT [Neptune Number],[Description],[Manufacturer],[Manufacturer P/N] FROM [All Components];"
cn.Open strConnection
Set rs = cn.Execute(strSql)
'Need Code here to get Info out of recordset
I am trying to get information out of the recordset that has the query result being dumped into it. I'm trying to figure out how to query the recordset and get the number of rows with a specific value in the "Neptune Number" field. I will then insert the correct number of rows into the worksheet I'm modifying. After that I need to get the data for that value and insert it into the worksheet.
Note: I don't care if recordset, datatable or anything else is used I simply need to be able to do what I described above. Please show code.
The easiest way to get where you I think you are asking to go is to modify your SQL statement changing
strSql = "SELECT [Neptune Number],[Description],[Manufacturer],[Manufacturer P/N] FROM [All Components];"
to
strSql = "SELECT [Neptune Number],[Description],[Manufacturer],[Manufacturer P/N] FROM [All Components] WHERE [Neptune Number] = 'Specific Value' ;"
This will force the sql query to only return the records you need. the .find method can be used for filtering the recordset, but i have avoided using it in this instance as it is cleaner to just ask the db for only the information that you want.
to process the recordset you can use the following
with rs
'will skip further processing if no records returned
if not (.bof and .eof) then
'assuming you do not need the headers
'loop through the recordset
do while not .eof
for i = 0 to .fields.count -1
'assuming the active sheet is where you want the data
cells(row, i + colOffset) = .fields(i).value
next
Rows(Row & ":" & Row).Insert
.movenext
loop
end if
end with
Where row is the starting point of your data and colOffset is the starting column of your data. Note that this code does not do things in the exact order you specified in your question (I am inserting rows as needed instead of calcualting the number of records up front.)
I have avoided using .recordcount because I find depending on the database used it will not return a correct record count.

TFS Team Query: get all changed work items since a given time

Apparently it is impossible to provide the Changed Date field with a timestamp (format '2009-12-14 10:00:00') when defining a new Team Query. I get the error: "The query failed. You cannot supply a time with the date when running a query using date precision.".
Is there a workaround for this? I just want a list of work items which are changed since the last 'x' minutes.
The solution is to write your own WIQL query: http://teamfoundation.blogspot.com/2008/01/specifying-date-and-time-in-wiql.html.
You to enter the date in the same format as it is displayed by VSTS: dd-MMM-YY (01-Jan-16).
In order to filter your items in TFS by a specific date, stick to this format:
try adding query parameter timePrecision:true. This worked for me
I ran into the same problem while trying to query for the latest updates and worked around it by doing the following
// defined elsewhere
private DateTime lastUpdated;
string consult = "select * from WorkItem where [Created Date] > ' " + lastUpdated.ToString("MM/dd/yy") +
"' AND [Work Item Type] = 'Test Case'";
IEnumerable<ITestCase> tcc = testManagementTeamProject.TestCases.Query(consult).Where(tp => tp.DateCreated > lastUpdated);
I did something very similar for retrieving test results
The last parameter of this query constructor lets you define the precision:
dayPrecision
When TRUE, indicates that a DateTime should resolve to an entire day. Often, it is TRUE to avoid being more precise about a specific time.

Resources