How to write a native SQL query in Grails 2.4.0? - mysql

I am working on Grails 2.4.0. I want to execute the native query in Groovy Controller. The query is as follow:
SELECT AVG(REPLACE(n.ep_text, 'PPM', '')), MONTH(n.date_creat)
from notification n
where n.type = 42
GROUP BY MONTH(n.date_creat)
Firstly, I execute the above query but it's have not found the REPLACE function like:
String query1 = "SELECT n.id, avg(REPLACE(n.epText, 'PPM', '')) FROM Notification as n";
def result = Notification.executeQuery(query1.toString())
How can I able to execute the REPLACE function in it?
And secondly, I have some R&D on it, but to execute the native query to required the sessionFactory. Unable to understand how to get the current session of Hibernate in Grails 2.4.0 to execute the native query?
Any help would be appreciated.

In order to use a native query, we can use SessionFactory, which is a bean and we can simply declare it to our Grails controller or service and dependency injection will handle it. Here is sample code using this bean to execute a native query.
class PublicService {
def sessionFactory
def getMatchedValue(){
def currentSession = sessionFactory.currentSession
def q = "select bank.id as id, bank.credit_amount as creditAmount, bank.debit_amount as debitAmount, bank.transaction_date as transactionDate, bank.transaction_name as transactionName, receipt.cr_date as crDate, receipt.picture_reference as pictureReference, receipt.receipt_date as receiptDate, receipt.reimbursment as reimbursment, receipt.total_amount as totalAmount, receipt.vendor as vendor " +
"from bank inner join receipt on bank.debit_amount=receipt.total_amount where ((bank.transaction_date >= receipt.receipt_date) and (bank.transaction_date <= DATE_ADD(receipt.receipt_date, INTERVAL 5 DAY) ))"//sample native query
def data = currentSession.createSQLQuery(q)
data.setResultTransformer(Criteria.ALIAS_TO_ENTITY_MAP);//if you are using alias for query e.g bank.credit_amount as creditAmount
final result = data.list()
return result
}
}

Related

mysql use case in jpa query

I am building an endpoint where 3 query param comes in request like
status(mendatory)
searchCriteria(optional)
startDate(optional)
I am considering that i have to write three(3) native sql queries with combination of ex.
1: status and searchCriteria
2: status and startDate
3: status and searchCriteria and startDate
but I do not want to write three queries,
I know it is possible to achieve in a single query using case .
This is my native sql query
#Query(value = "select * from email_info u where u.status =:status and u.campaign =:searchCriteria and u.scheduleat =:startDate",
nativeQuery = true)
object getPromotional(String status, String searchCriteria, String startDate);
How to use case in above query using jpa like
CASE
WHEN :searchCriteria != null THEN u.campaign =:searchCriteria
WHEN :startDate != null THEN u.scheduleat =:startDate
END

what it the JPQL jpa (#Query) for update column with binary operator mysql query?

SQL Query:
update de_meta set service_lines = service_lines | 5 where de_id = 20;
This works fine from SQL console.
JPA Query:
#Modifying
#Query("update DeMetaEntity set serviceLines = serviceLines | ?2 where deId = ?1")
void addDeServiceLineMap(Integer deId, int serviceLine);
This JPA query throws error because | (bitwise OR) is not valid in JPQL.
Is there any way to write equivalent JPQL for given SQL query?
I don't want to use criteria queries. As I use this at JAVA INTERFACE.
Create a native query as Alan suggested:
#Modifying
#Query("update de_meta set service_lines = service_lines | ?2 where de_id = ?1", nativeQuery=true)
void addDeServiceLineMap(Integer deId, int serviceLine);
The switch nativeQuery=true will execute the SQL query as it is.

Hibernate query for employee with date

This is my code.. Query working when i search with mysql query(find it in screenshot).But failed with hiberbate query.
EmployeeAttendanceMaster masterEmployeeFromRepository = masterEmployeeRepository.findById(employee, date);
if (masterEmployeeFromRepository == null) {
System.out.println("SignIn Successfully");
}else System.out.println("You are already Logged In");
masterEmployeeRepository:
#Query("select me from EmployeeAttendanceMaster me where me.employee = ?1 and Date(me.date) = ?2 order by me.date desc")
EmployeeAttendanceMaster findById(Employee employee,Date date);
mysql db screenshot in with same query
Data with same date there in db..So it shoudnot go through if condition.It should follow else condition.But as long as i tried this it prints "SignIn Successfully"
Thanks advance
You are using the Spring Data JPA #Query annotation (as discerned from the full data type you have provided in the comments to your question). The query you specify with #Query (select me from EmployeeAttendanceMaster me ...) must be a valid JPA Query Language (JPQL) statement. From what I know and remember, JPQL does not have a Date() function. So, your query is invalid because it contains Date(me.date) which refers to a non-existent JPQL Date() function, even if you can run it directly on MySQL.
You can change your query declaration to:
#Query(value = "select * from EmployeeAttendanceMaster where employee_id = ?1 and Date(date) = ?2 order by date desc", nativeQuery = true)
This will force the JPA provider (Hibernate in your case) to treat the query as a native SQL query and will be executed on the underlying database without any translation. You will lose database independence though.

SQLAlchemy MySQL IF Statement

I'm in the middle of converting an old legacy PHP system to Flask + SQLAlchemy and was wondering how I would construct the following:
I have a model:
class Invoice(db.Model):
paidtodate = db.Column(DECIMAL(10,2))
fullinvoiceamount = db.Column(DECIMAL(10,2))
invoiceamount = db.Column(DECIMAL(10,2))
invoicetype = db.Column(db.String(10))
acis_cost = db.Column(DECIMAL(10,2))
The query I need to run is:
SELECT COUNT(*) AS the_count, sum(if(paidtodate>0,paidtodate,if(invoicetype='CPCN' or invoicetype='CPON' or invoicetype='CBCN' or invoicetype='CBON' or invoicetype='CPUB' or invoicetype='CPGU' or invoicetype='CPSO',invoiceamount,
fullinvoiceamount))) AS amount,
SUM(acis_cost) AS cost, (SUM(if(paidtodate>0,paidtodate,invoiceamount))-SUM(acis_cost)) AS profit FROM tblclientinvoices
Is there an SQLAlchemyish way to construct this query? - I've tried googling for Mysql IF statments with SQlAlchemy but drew blanks.
Many thanks!
Use func(documentation) to generate SQL function expression:
qry = select([
func.count().label("the_count"),
func.sum(func.IF(
Invoice.paidtodate>0,
Invoice.paidtodate,
# #note: I prefer using IN instead of multiple OR statements
func.IF(Invoice.invoicetype.in_(
("CPCN", "CPON", "CBCN", "CBON", "CPUB", "CPGU", "CPSO",)
),
Invoice.invoiceamount,
Invoice.fullinvoiceamount)
)
).label("amount"),
func.sum(Invoice.acis_cost).label("Cost"),
(func.sum(func.IF(
Invoice.paidtodate>0,
Invoice.paidtodate,
Invoice.invoiceamount
))
- func.sum(Invoice.acis_cost)
).label("Profit"),
],
)
rows = session.query(qry).all()
for row in rows:
print row

HQL Query fails in Hibernate MySQL

I want to recuperate all rows from user table.
String queryS = "select u from user u";
System.out.println("entityManager: "+(entityManager == null));
Query query = entityManager.createQuery(queryS);
//staff
The line that throws the exception is Query query = entityManager.createQuery(queryS);
I don't know why even persistance file is ok and the table exists
The stack is:
10:36:06.693 [AWT-EventQueue-0] DEBUG org.hibernate.hql.ast.ErrorCounter - throwQueryException() : no errors
10:36:06.693 [AWT-EventQueue-0] DEBUG o.h.hql.antlr.HqlSqlBaseWalker - select << begin [level=1, statement=select]
You have to put the name of the table in the query as in the persistence file not in database.
If this:
String queryS = "select u from user u"
Is referred on table name you can't use createQuery method but createNativeQuery
If you want to use createQuery you must use in your query the entity/class mapped youe user table
Summarizing:
Case 1 (use createNativeQuery)
String queryS = "select u from user u";
Query query = entityManager.createNativeQuery(queryS);
Case 2 (use createQuery)
String queryS = "select u from " + User.class.getName() + " u";
Query query = entityManager.createNativeQuery(queryS);