mySQL Subquery to Stored Procedure or JPA query - java

(Edit 1: not Date but wc_Event.date)
I created a query (with subquery) that executes perfectly but I have trouble converting it either to a JPA query or a stored procedure.
This is my query:
SELECT * FROM wc_Event WHERE (wc_Event.date > CURRENT_DATE())
AND wc_Event.evt_id IN
(
SELECT event_users.evt_id FROM event_users
WHERE event_users.usr_id = 1
)
ORDER BY wc_Event.date
I have tried this for stored procedure:
CREATE PROCEDURE getFutureRegistredEvents
(
my_user_id int
)
BEGIN
SELECT * FROM wc_Event WHERE (wc_Event.date > CURRENT_DATE())
AND wc_Event.evt_id IN
(
SELECT event_users.evt_id FROM event_users
WHERE event_users.usr_id = my_user_id
)
ORDER BY wc_Event.date
END
It tells me to use the right syntax at line 13 (= END) but even if I add a semicolon to it my query wont work.
I also tried creating the same effect with JPA queries but with no effect.
What am I doing wrong?
Thanks in advance
Bert

Related

Hibernate paging query returns no records with DB2/400 dialect

I am using Vaadin Flow together with Spring-data-jpa and Hibernate with DB2/400 dialect. I am trying to use paging queries as my dataset could be very large. I have Hibernate logging on so that I can see the statements that Hibernate is executing. It works for the first page as the Hibernate query just asks for the first 50 records. However for the second page it asks for 100 records and filters out the first 50 but the query does not return any results. A slightly simplified version of the Hibernate generated query is:
select * from (
select inner2_.*, rownumber() over(order by order of inner2_) as rownumber_ from (
select * from flxalll1 flxalll1x0_ where upper(flxalll1x0_.aoukey) like upper('%te%') fetch first 100 rows only
) as inner2_
) as inner1_ where rownumber_ > 50 order by rownumber_;
I have run this myself using the IBMi Run SQL Script tool and no results are returned. However, if I just do the inner two selects:
select inner2_.*, rownumber() over(order by order of inner2_) as rownumber_ from (
select * from flxalll1 flxalll1x0_ where upper(flxalll1x0_.aoukey) like upper('%te%') fetch first 100 rows only
) as inner2_ ;
I get the expects list of result, though of course all of them and not just the last 50. I have done some more experimentation and discovered that (unsurprisingly) this works:
select * from (
select * from flxalll1
);
in that it lists all the records, but this:
select * from (
select * from (
select * from flxalll1
)
);
produces no records.
Obviously there is no sense in that but I'm wondering if there is a problem with DB2/400 in that it won't do a select with two nested sub-selects, or something like that, and is that the reason why my original query does not return any records?
Solving the problem could be tricky but for now at least I am just trying to work out where the problem lies.
I have now solved my problem by not using the (IBMi) logical as mentioned in my comment above but by allowing spring data jpa to do the UNION. I created an abstract super class for my 10 tables and changed their Java class declarations to extend it.
I am indebted to this post and to the answer by Patrice Blanchardie:
Union tables with spring data jpa

PostgreSQL query works in pgAdmin but not in Java EclipseLink

I have a SQL that counts rows per date truncate (months, days, hours). Think a history graph. Query works fine if executed in pgAdmin but fails in Java using EclipseLink.
pgAdmin query:
SELECT date_trunc( 'hour', delivered_at ),
COUNT(date_trunc( 'hour', delivered_at )) AS num
FROM messages
WHERE channel_type='EMAIL'
AND created_at>='2016-02-28 16:01:08.882'
AND created_at<='2016-02-29 16:01:08.882'
GROUP BY date_trunc( 'hour', delivered_at );
JPQL Named query
SELECT FUNCTION('date_trunc', 'hour', m.deliveredAt ),
COUNT(FUNCTION('date_trunc', 'hour', m.deliveredAt )) AS num
FROM Message m
WHERE m.channelType = :channelType
AND m.createdAt >= :fromDate
AND m.createdAt <= :toDate
GROUP BY FUNCTION('date_trunc', 'hour', m.deliveredAt )
EclipseLink debugging log:
SELECT date_trunc(?, delivered_at), COUNT(date_trunc(?, delivered_at)) FROM messages
WHERE (((channel_type = ?) AND (created_at >= ?)) AND (created_at <= ?)) GROUP BY date_trunc(?, delivered_at)
bind => [hour, hour, EMAIL, 2015-12-27 00:00:00.0, 2015-12-27 00:00:00.0, hour]
Error:
ERROR: column "messages.delivered_at" must appear in the GROUP BY
clause or be used in an aggregate function Position: 23
PostgreSQL log:
2016-03-01 13:22:08 CET ERROR: column "messages.delivered_at" must
appear in the GROUP BY clause or be used in an aggregate function at
character 23 2016-03-01 13:22:08 CET STATEMENT: SELECT date_trunc($1,
delivered_at), COUNT(delivered_at) FROM messages WHERE (((channel_type
= $2) AND (created_at >= $3)) AND (created_at <= $4)) GROUP BY date_trunc($5, delivered_at) 2016-03-01 13:22:08 CET LOG: execute
S_2: SELECT 1
If I replace the binded variables from EclipseLink logged query and execute it in pgAdmin the query works. What is going on here?
Edit: Just to clarify, it also works using em.createNativeQuery.
PostgreSQL can have trouble with resolving parameter binding, which in this case manifests as native SQL with parameters inline work, while JPA generated SQL which defaults to bound parameters fails.
One solution is to turn off parameter binding by passing "eclipselink.jdbc.bind-parameters" with a value of "false" as either a query hint for the specific query, or as a persistence unit property to turn off parameter binding by default for all queries.
On postgresql, you can use the following syntax
GROUP BY 1
That means you will group you agregate using the first selected attribute in the SELECT clause. That might be helpful there

Same stored procedure with createSQLQuery and getNamedQuery in Hibernate giving different behaviour

I am calling stored procedure named PRC_HB_EMP_SP1 from below code, it is giving expected output.
Session session = HibernateUtil.getSessionFactory().openSession();
Query query = session.getNamedQuery("PRC_HB_EMP_SP1");
query.setParameter("IN_EMPID",empId);
but, when I am calling same procedure with below code
Query query1 = session.createSQLQuery("CALL PRC_HB_EMP_SP1(?,:IN_EMPID)").addEntity(Employee.class);
query1.setParameter("IN_EMPID",empId);
It is giving me error like
org.hibernate.QueryException: Expected positional parameter count: 1, actual parameters: [] [CALL PRC_HB_EMP_SP1(?,:IN_EMPID)]
what can be the reason behind this? I searched on net, i got to know this is issue of paramateres but this sp is having two parameters. first is ouput parameter, second is input parameter
sp
create or replace PROCEDURE PRC_HB_EMP_SP1
(
Out_value OUT SYS_REFCURSOR,
IN_EMPID NUMBER
)
AS
BEGIN
open Out_value for
SELECT EMPID,EMPNAME,ADDRESS,SALARY,EMPAGE
FROM EMPLOYEE
WHERE EMPLOYEE.EMPID = IN_EMPID;
END PRC_HB_EMP_SP1;
I gone through same situation.I tried another way...
Instead using out parameter in stored procedure,modify your procedure like below
create or replace PROCEDURE PRC_HB_EMP_SP1
(
IN_EMPID NUMBER
)
AS
BEGIN
open Out_value for
SELECT EMPID,EMPNAME,ADDRESS,SALARY,EMPAGE
FROM EMPLOYEE
WHERE EMPLOYEE.EMPID = IN_EMPID;
select Out_value;
END PRC_HB_EMP_SP1;
now ,
Query query1 = session.createSQLQuery("CALL PRC_HB_EMP_SP1(:IN_EMPID)").addEntity(Employee.class);
query1.setParameter("IN_EMPID",empId);
and get your out value using,
List res=query1.list();
System.out.println("result"+res.get(0));

MySQL Simple Query Error

I am new to MySQL and I wrote a simple query bellow:
CREATE Table tblFeedBack
(
`FeedBackID` INT AUTO_IncremeNT,
`UserID` INT,
`Inserted_TS` TIMESTAMP ,
`FeedBackValue` VARCHAR(100),
PRIMARY KEY (FeedBackID)
);
CREATE PROCEDURE tblFeedBack_InsertUpdate
(
IN U_ID INT,
IN FB_Value VARCHAR(50)
)
BEGIN
IF ((Select COUNT(*) From 'tblFeedback') < 3)
BEGIN
INSERT INTO 'tblFeedBack' (`UserID`,`FeedBackValue`)
VALUES (U_ID,FB_Value);
END
ELSE
BEGIN
DECLARE #MostRecentFID INT;
SELECT TOP 1 `FeedBackID` FROM tblFeedback
WHERE UID = U_ID
ORDER BY `Inserted_TS` DESC
INTO #MostRecentFID;
UPDATE tblfeedback
SET `FeedBackValue` = #FeedBackValue
WHERE `FeedBackID` = #MostRecentFID
END
END
I am getting this error:
Schema Creation Failed: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''tblFeedBack' (`UserID`,`FeedBackValue`) VALUES (1,'12')' at line 9
Can anyone please help me solve this one?
Thanks in advance.
MySQL does not supportĀ TOP you want to use LIMIT 1 instead as they are ordered.
Select `FeedBackID` FROM tblFeedback
WHERE UID = U_ID
ORDER BY `Inserted_TS` DESC
LIMIT 1
INTO #MostRecentFID;
Also, when you query a table using quotes it becomes case sensitive.
IF ((Select COUNT(*) From 'tblFeedback') < 3)
Should be
IF ((Select COUNT(*) From 'tblFeedBack') < 3)
Fix these 2 errors and it should work.
The table names are different in the insert query. One contains 'tblFeedback' and other contains 'tblFeedBack'
Also, please try to remove single quotes near table names in the query.

stored procedures, error #1312, CLIENT_MULTI_RESULTS flag

i am writing stored procedures in MySQL that return values;
CREATE PROCEDURE getCustomerById (id int)
BEGIN
SELECT *
FROM customer
WHERE customer.id = id;
END;
and i get the error that the results cannot be shown in the given context.
after some googling, i think that i need to set the flag "CLIENT_MULTI_RESULTS" - i am connecting the database from JDBC using a java app, but cant find where to set it!
any suggestions?
try this
delimiter ;
drop procedure if exists getCustomerById;
delimiter #
create procedure getCustomerById
(
in p_id int unsigned
)
begin
select c.* from customer c where c.id = p_id;
end #
delimiter ;

Categories