How to make LIMIT work in Grails HQL executeUpdate()? - grails

I'm running grails 1.3.6 and I have this code:
String hql = '''
UPDATE
ApiResponse a
SET
a.lockId = :lockId
WHERE
a.lockId = 0
ORDER BY
a.dateAdded asc
LIMIT 5
'''
ApiResponse.executeUpdate(hql, [lockId : workerId])
It seems that this code updates all rows in DB instead of the 5 oldest entries. Does this mean LIMIT is not working in HQL? Please help me how to achieve the same SQL logic in GORM or HQL. Basically, I need to do a bulk update using LIMIT.

what i do (grails 1.3.7):
ExAus.executeQuery( "select distinct <field> from <controller>", [max: 20, offset: 0] )

While waiting for someone to reply, I think I found a workaround. Here it is:
def c = ApiResponse.createCriteria()
def targetList = c.list {
eq('lockId', 0)
maxResults(5)
order("dateAdded", 'asc')
}
String hql = '''
UPDATE
ApiResponse
SET
lockId = :lockId
WHERE
id in (:ids)
'''
ApiResponse.executeUpdate(hql, [lockId : workerId, ids: targetList.collect {it.id}])
I believe this approach can still be considered same logic with the original. However, this has to make 2 queries.
Feel free to suggest other approaches. Thanks!

I know the post is quite old but the question is still relevant since I had the same problem.
I fell back to using Groovy sql (jdbc) instead.
You will need to inject the dataSource object within your service/controller first by using:
def dataSource
Then you may do this in your method:
String sqlQuery = '''
UPDATE
API_RESPONSE a
SET
a.LOCK_ID = :lockId
WHERE
a.LOCK_ID = 0
ORDER BY
a.DATE_ADDED asc
LIMIT 5
'''
def sql = new Sql(dataSource)
sql.executeUpdate(sqlQuery, [lockId : workerId])
Note that you will need to use the database native table and column names in the sql query.

Related

Executing simple query issue in Zend 2

I want to execute two queries in zend 2 :
This is the content of my model file:
$email = $getData['login_email'];
$password = $getData['login_password'];
$select = $this->adapter->query ("select count(*) as counter from users where email = '$email' and password = '".md5($password)."'");
$results = $select->execute();
if ($results->current()['counter'] == 1 ){
// $update_user = $this->adapter->query("UPDATE users SET session_id = '".$session_id."' WHERE email = '".$email."'");
try {
$update_user = $this->adapter->query("select * from users");
} catch (\Exception $e) {
\Zend\Debug\Debug::dump($e->__toString()); exit;
}
$update_session = $update_user->execute();
For some reason if i remove one random query, the another one will be executed. I know it is weird but i believe there is a rational answer to it. The result of the try catch part is:
I did not write it wrong the query. AS you can see I tried a simple select query and i got the same result. Actually I have no idea what is wrong this. Please help with this, I'm looking up for an answer on the internet during the last 5-6 days and I found nothing. If you want me to provide any more information, please ask. THX
As this answer suggests, this is an issue with the mysqli driver using unbuffered queries by default.
To fix this, you have to buffer the result of the first query before running the next one. With ZF2, the Result interface has a buffer() method to achieve this :
$results = $select->execute();
$results->buffer();

Grails: Convert the Hql query to GORM

Kindly, Convert this below hql query to GORM either using criteria or using some API. I am new to grails and I searched enough but I did't get any positive solution for this forgive me if it is simple.
MappingDetail.executeQuery("select map.id from MappingMaster as map where map.id = (select mapdetail.id from MappingDetail as mapdetail where mapdetail.rawdata_template.id=(select rawdata.id from RawDataMasterTemplate as rawdata where rawdata.name like :name))",[name:'%Rick%'])
Why do you have to use criteria here? I think this is the select where you use HQL instead.
def raw = RawDataMasterTemplate.findByNameLike('%Rick%')
def detail = MappingDetail.findByRawdata_template(raw)
def master = MappingMaster.get(detail?.id)
Test this:
MappingMaster.withCriteria {
createAlias 'mappingDetail', 'mp'
createAlias 'mp.rawDtaMasterTemplate', 'rd'
projections {
property 'id'
}
ilike 'rd.name', '%Rick%'
}

Ruby on Rails Active Record Query - counting records

Hi I'm new to rails and developing an application to pull results from database in preparation for charting. I have the following code in my controller:
#statistic = OutstandingWorkIndex.find_by_sql ["SELECT Result_Set.Set_Code, Request.Specimen_Number ,
DATEDIFF('hh',Result_Set.Date_Time_Booked_In,current_timestamp) as HrsIn FROM iLabTP.Outstanding_Work_Index, iLabTP.Result_Set Result_Set, iLabTP.Request
WHERE Outstanding_Work_Index.Request_Row_ID = Result_Set.Request_Row_ID and Outstanding_Work_Index.Request_Row_ID = Request.Request_Row_ID and Result_Set.Set_code=?
order by Result_Set.Date_Time_Booked_In DESC", params[:set_code].upcase]
What I'd like to do is count the number of records returned in addition to the object from above which I then use to create and XML stream of paired values or use the google charts java script api in the view.
Do I need to issue commands like:
#statistic = OutstandingWorkIndex.find_by_sql ["SELECT Result_Set.Set_Code, Request.Specimen_Number ,
DATEDIFF('hh',Result_Set.Date_Time_Booked_In,current_timestamp) as HrsIn
FROM iLabTP.Outstanding_Work_Index, iLabTP.Result_Set Result_Set, iLabTP.Request
WHERE Outstanding_Work_Index.Request_Row_ID = Result_Set.Request_Row_ID and Outstanding_Work_Index.Request_Row_ID = Request.Request_Row_ID and Result_Set.Set_code=?
order by Result_Set.Date_Time_Booked_In DESC", params[:set_code].upcase].**count**
And if so does this result in the query being reissued?
Thanks
You should do:
#size = #statistic.size
It's well explained here.

grails webflow select statement problem

i use webflow in a my grails application, i have 2 tables with relation ManyToMany in hibernate mode. this relation as u know, creates a table with 2 primary keys of the original tables, both be the primary key of the third table.
my tables are destination and destinationGroup.
i write a select statement with dynamic finders to have a list of destnation group that has specific destination.
i try these ways and no effect for any one:
1-
def DestinationInstance = Destination.get(params.destination)
flow.DestinationGroupList = DestinationGroup.executeQuery("select distinct d.name,d.description from DestinationGroup d where d.destinations = :p",[p:DestinationInstance])
2-
def DestinationInstance = Destination.get(params.destination)
flow.destinationGroupList = DestinationGroup.findAllWhere(Destinations:destinationInstance)
3-
def DestinationInstance = Destination.get(params.destination)
flow.destinationGroupList = DestinationGroup.findAll("from DestinationGroup as d where d.destinations =:p", [p:destinationInstance]
)
these 3 statement has no effect, if there is any why for solving this problem please till me about it.
thanks
Have you tried a Criteria query?
def c = DestinationGroup.createCriteria()
flow.destinationGroupList = c.list{
destinations{
idEq(destinationInstance.id)
}
}

How to querying across databases with grails?

Is there a way to querying across 2 databases in grails ?
Example (I made a select on two databases - works and test) :
select
c.crf_name,
c.crf_id,
ig.group_id,
ig.group_name,
from
works.crfs c,
test.item_groups ig;
1) I would like to query against two databases, and attach results to a domain.
Or :
2) Is it possible to mixing one query part with data from database and other part with domain class ?
Edit : I need to do a single query mixing tables from 2 databases (one db is PostgreSQL and other db is Mysql). So, in grails is it possible to mix to dataSources beans in one query ?
Edit 2 : Here a better example :
select
igm.item_id,
igm.item_group_id as group_id,
igm.crf_version_id,
ig.name as group_name
from
works.item_group_metadata igm,
test.item_group ig
where
igm.item_group_id=ig.item_group_id
;
If you are planning to do your own sql (like it seems to be the case) over 2 datasources, I suggest that you define your 2 datasources as Spring beans in grails-app/conf/spring.
e.g. (drop your db drivers in /lib and replace the values to match your RDBMS drivers and connection string) :
import org.apache.commons.dbcp.BasicDataSource
import oracle.jdbc.driver.OracleDriver
beans = {
worksDataSource(BasicDataSource) {
driverClassName = "oracle.jdbc.driver.OracleDriver"
url = "jdbc:oracle:thin:#someserver:someport:works"
username = "works"
password = "workspassword"
}
testDataSource(BasicDataSource) {
driverClassName = "oracle.jdbc.driver.OracleDriver"
url = "jdbc:oracle:thin:#someserver:someport:test"
username = "test"
password = "testpassword"
}
}
Then create a service to handle your queries, like :
import groovy.sql.Sql
class SomeService {
def worksDataSource
def testDataSource
def query1 = """
SELECT crf_name, crf_id
FROM works.crfs
"""
def query2 = """
SELECT group_id, group_name
FROM test.item_groups
"""
def sqlWorks = Sql.newInstance(query1)
def sqlTest = Sql.newInstance(query2)
// Then do whatever you like with the results of the 2 queries
// e.g.
sqlWorks.eachRow{ row ->
def someDomainObject = new SomeDomainObject(prop1 : row.crf_name, prop2 : crf_id)
someDomainObject.otherProp = whateverYouLike()
someDomainObject.save()
}
}
Your query doesn't have a where clause so I don't know how you want to relate the data coming from your 2 tables...
If you want to do a single query mixing tables from 2 databases, (ask your DBA to) establish a DBLink between databases test and works and perform the query on the datasource containing the DBLink.
I hope this helps.
You should use a "UNION SELECT" which is supported by most databases. Make sure that both select statements have the same number of columns.
select
crf_name,
crf_id
from
ig
UNION SELECT
group_id,
group_name
from
id
A union select concatenates the results for 2 queries, for example:
select 1 union select 2
Have you looked at the Datasources plugin? It sounds like it will do what you require, but I think you'd need to use HQL or finders on the domain objects directly, rather than SQL, for it to work.
I haven't used the plugin myself but I'd be interested to hear how it goes it you try it.
HTH

Resources