How do i deal with this multiple parameters issue in mybatis - mybatis

I've tried to write a query using mapper of mabatisbut can't make it so far
This is my code
String SQL_SELECTPAGE = "select b.writer, b.title, b.topicdate, b.lecturekey, b.tcontent" +
"from (select rownum rn, a.* from (select * from topics WHERE LECTUREKEY = #{lid}" +
"order by topicdate desc) a) b" +
"where rn between #{c.start} and #{c.end}";
#Select(SQL_SELECTPAGE)
List<Topics> selectPage(#Param("lid") String lid, #Param("c") PaginationCriteria c);
PaginationCriteria has start and end attribute.
Below is HTTP Status 500 error message. I think parameter couldn't pass
... WHERE LECTUREKEY = ?order by topicdate desc) a) bwhere rn between ? and ? > ### Cause: java.sql.SQLSyntaxErrorException: ORA-00936:
I'd be glad if someone can help me
Thank you

You can't use a JDBC bind parameter for the row number clause. In MyBatis, anything specified with #{...} is a bind parameter. Anything you specify as ${...} is, basically, string substitution which should work here.
So rewrite your where clause like this where rn between ${c.start} and ${c.end}

Related

relation "table name" does not exist but it was set in FROM

I'm trying to use a sub-query in the "FROM" section but later get errors "Relation "Table name" does not exist".
I have tried to copy paste my sub-query which works, but creates really long and ugly code, as what I am sending is just a part of the whole thing which represents the same problem.
SELECT Reporter.rid , Reporter.fname , Reporter.lname
FROM Reporter , report , map , keyword , ( SELECT Reporter.rid
FROM Reporter , report , map ,
keyword
WHERE (Reporter.rid = report.rid
AND report.iid = map.iid
AND map.kword =
keyword.kword AND
keyword.subject <>
'health')
) AS nonH
WHERE (Reporter.rid NOT IN(SELECT * FROM nonH) AND Reporter.rid = report.rid)
I would expect this code to work and present me all Reporters who are not linked to anything but 'health'
Error msg is:
ERROR: relation "nonh" does not exist LINE 7: WHERE (Reporter.rid NOT
IN(SELECT * FROM nonH) AND Reporter....
You can't use a derived table in a subquery like that. You either have to reapeat the query for it:
SELECT reporter.rid,
reporter.fname,
reporter.lname
FROM reporter,
report,
map,
keyword,
(SELECT reporter.rid
FROM reporter,
report,
map,
keyword
WHERE reporter.rid = report.rid
AND report.iid = map.iid
AND map.kword = keyword.kword
AND keyword.subject <> 'health') AS nonh
WHERE reporter.rid NOT IN (SELECT reporter.rid
FROM reporter,
report,
map,
keyword
WHERE reporter.rid = report.rid
AND report.iid = map.iid
AND map.kword = keyword.kword
AND keyword.subject <> 'health')
AND reporter.rid = report.rid);
Or you can use a common table expression:
WITH
nonh
AS
(
SELECT reporter.rid
FROM reporter,
report,
map,
keyword
WHERE reporter.rid = report.rid
AND report.iid = map.iid
AND map.kword = keyword.kword
AND keyword.subject <> 'health'
)
SELECT reporter.rid,
reporter.fname,
reporter.lname
FROM reporter,
report,
map,
keyword,
nonh
WHERE reporter.rid NOT IN (SELECT rid
FROM nonh)
AND reporter.rid = report.rid);
That may fix your immediate problem. But to be honest, you query is quite a mess with all that implicit joins of tables which's columns are never used and hard to follow, let alone guess what you might be after. I recommend you rewrite it using explicit INNER JOIN/CROSS JOIN/... syntax. And question yourself what the cross joins are actually good for and if they're really needed.
there is no table called "nonH". You are creating an "nonH" alias to a subquery in your SELECT clause, but that does not create a persistent object with that name.

Issue with JPA statement "translation"

I have a JPA statement which is like this
select p from Proposal p where p.creationTime > :startDate AND p.creationTime < :stopDate AND ((p.owner = :owner) OR (:member MEMBER OF p.sharedWithTeam.members)) ORDER BY p.creationTime DESC
But it never generates any result. I use EclipseLink.
After digging a bit into the generated SQL, I found out that it translates the query into something that can never be true!
SELECT XXX FROM userteam_users t3, USERTEAM t2, USERS t1, PROPOSAL t0 WHERE ((((t0.CREATIONTIME > ?) AND (t0.CREATIONTIME < ?)) AND ((t0.OWNER_username = ?) OR (? = t1.username))) AND ((t2.ID = t0.SHAREDWITHTEAM_ID) AND ((t3.teams_ID = t2.ID) AND (t1.username = t3.members_username)))) ORDER BY t0.CREATIONTIME DESC LIMIT ? OFFSET ?
(I only included the from and where clause to make it shorter...)
I can't see what is wrong with my JPQL query. Could it be my use of "OR"? or my "bold" use of the member of condition?
EDIT: in fact, the statement can be true, I misread it. BUT I have proposals with NO shared user team, so the first condition is always false in this case, and it should be true (in my view)
Thanks!

PostgreSql Group By and aggreate function error

My problem is, when I run the following query in MySQL, it looks like this
Query;
SELECT
CONCAT(b.tarih, '#', CONCAT(b.enlem, ',', b.boylam), '#', b.aldigi_yol) AS IlkMesaiEnlemBoylamImei,
CONCAT(tson.max_tarih, '#', CONCAT(tson.max_enlem, ',', tson.max_boylam), '#', tson.max_aldigi_yol) AS SonMesaiEnlemBoylamImei,
Max(CAST(b.hiz AS UNSIGNED)) As EnYuksekHiz,
TIME_FORMAT(Sec_TO_TIME(TIMESTAMPDIFF(SECOND, (b.tarih), (tson.max_tarih))), '%H:%i') AS DurmaSuresi
FROM
(Select id as max_id, tarih as max_tarih, enlem as max_enlem, boylam as max_boylam, aldigi_yol as max_aldigi_yol from _213gl2015016424 where id in(
SELECT MAX(id)
FROM _213gl2015016424 where (tarih between DATE('2016-11-30 05:45:00') AND Date('2017-01-13 14:19:06')) AND CAST(hiz AS UNSIGNED) > 0
GROUP BY DATE(tarih))
) tson
LEFT JOIN _213gl2015016424 a ON a.id = tson.max_id
LEFT JOIN _213gl2015016424 b ON DATE(b.tarih) = DATE(a.tarih)
WHERE b.tarih is not null And (b.tarih between DATE('2016-11-30 05:45:00') AND Date('2017-01-13 14:19:06')) AND b.hiz > 0
GROUP BY tson.max_tarih
Output is order by date;
Result query
When I try to run a query in PostgreSQL, I get group by mistake.
Query;
SELECT
CONCAT(b.tarih, '#', CONCAT(b.enlem, ',', b.boylam), '#', b.toplamyol) AS IlkMesaiEnlemBoylamImei,
CONCAT(tson.max_tarih, '#', CONCAT(tson.max_enlem, ',', tson.max_boylam), '#', tson.max_toplamyol) AS SonMesaiEnlemBoylamImei,
Max(CAST(b.hiz AS OID)) As EnYuksekHiz,
to_char(to_timestamp((extract(epoch from (tson.max_tarih)) - extract(epoch from (b.tarih)))) - interval '2 hour','HH24:MI') AS DurmaSuresi
FROM
(Select id as max_id, tarih as max_tarih, enlem as max_enlem, boylam as max_boylam, toplamyol as max_toplamyol from _213GL2016008691 where id in(
SELECT MAX(id)
FROM _213GL2016008691 where (tarih between DATE('2018-02-01 03:31:54') AND DATE('2018-03-01 03:31:54')) AND CAST(hiz AS OID) > 0
GROUP BY DATE(tarih))
) tson
LEFT JOIN _213GL2016008691 a ON a.id = tson.max_id
LEFT JOIN _213GL2016008691 b ON DATE(b.tarih) = DATE(a.tarih)
WHERE b.tarih is not null And (b.tarih between DATE('2018-02-12 03:31:54') AND DATE('2018-02-13 03:31:54')) AND b.hiz > 0
GROUP BY tson.max_tarih
Group by error is : To use the aggregate function, you must add the column "b.tarih" to the GROUP BY list.
When I add it I get the same error for another column.I'm waiting for your help.
You are using a feature of MySQL that is not standard SQL and you can also deactivate.
You are grouping by tson.max_tarih in your query. That means that for all rows that share the same value in that field, you will get only one row as a result of that group.
If you have several different values in the rest of the fields (enlem, boylam, etc...) which one are you trying to get in as the result of the query? That's the question that PostgreSQL is asking you.
MySQL is just returning any value for those fields among the rows in the group. PostgreSQL requires you to actually specify it.
Two typical solutions would be grouping by the rest of the fields (b.tarih, b.enlem) or specifying the value those fields to something like MAX(b.tarih), etc.

Symfony DQL Postgresql group by isnt working

I have just switched from mysql to postgresql and my working dql queries stopped working.
Here is my dql
SELECT p
FROM AppBundle:Photo p
JOIN AppBundle:Like l WITH p = l.photo
WHERE p.isModerated = :isModerated
AND p.isActive = :isActive
AND p.category IN(:categories)
AND p.creationDate <= :begin
AND p.creationDate >= :end
GROUP BY p.id
ORDER BY l.creationDate DESC
Getting the next error
SQLSTATE[42803]: Grouping error: 7 ERROR: column "l1_.creation_date" must appear in the GROUP BY clause or be used in an aggregate function
LINE 1: ... p0_.creation_date >= $4 GROUP BY p0_.id ORDER BY l1_.creati...
As i can understand, it says that group by column should be in SELECT. I dont it to be there. I need to select just p (AppBundle:Photo) and nothing more. What should be edited in dql to get it working properly?
Thank you.
I just replaced ORDER BY l.creationDate DESC to ORDER BY p.creationDate DESC
It will work for me. As i understood, ORDER BY column should be SELECTed

TSQL CTE Error: Incorrect syntax near ')'

I am developing a TSQL stored proc using SSMS 2008 and am receiving the above error while generating a CTE. I want to add logic to this SP to return every day, not just the days with data. How do I do this? Here is my SP so far:
ALTER Proc [dbo].[rpt_rd_CensusWithChart]
#program uniqueidentifier = NULL,
#office uniqueidentifier = NULL
AS
DECLARE #a_date datetime
SET #a_date = case when MONTH(GETDATE()) >= 7 THEN '7/1/' + CAST(YEAR(GETDATE()) AS VARCHAR(30))
ELSE '7/1/' + CAST(YEAR(GETDATE())-1 AS VARCHAR(30)) END
if exists (
select * from tempdb.dbo.sysobjects o where o.xtype in ('U') and o.id = object_id(N'tempdb..#ENROLLEES')
) DROP TABLE #ENROLLEES;
if exists (
select * from tempdb.dbo.sysobjects o where o.xtype in ('U') and o.id = object_id(N'tempdb..#DISCHARGES')
) DROP TABLE #DISCHARGES;
declare #sum_enrollment int
set #sum_enrollment =
(select sum(1)
from enrollment_view A
join enrollment_info_expanded_view C on A.enrollment_id = C.enroll_el_id
where
(#office is NULL OR A.group_profile_id = #office)
AND (#program is NULL OR A.program_info_id = #program)
and (C.pe_end_date IS NULL OR C.pe_end_date > #a_date)
AND C.pe_start_date IS NOT NULL and C.pe_start_date < #a_date)
select
A.program_info_id as [Program code],
A.[program_name],
A.profile_name as Facility,
A.group_profile_id as Facility_code,
A.people_id,
1 as enrollment_id,
C.pe_start_date,
C.pe_end_date,
LEFT(datename(month,(C.pe_start_date)),3) as a_month,
day(C.pe_start_date) as a_day,
#sum_enrollment as sum_enrollment
into #ENROLLEES
from enrollment_view A
join enrollment_info_expanded_view C on A.enrollment_id = C.enroll_el_id
where
(#office is NULL OR A.group_profile_id = #office)
AND (#program is NULL OR A.program_info_id = #program)
and (C.pe_end_date IS NULL OR C.pe_end_date > #a_date)
AND C.pe_start_date IS NOT NULL and C.pe_start_date >= #a_date
;WITH #ENROLLEES AS (
SELECT '7/1/11' AS dt
UNION ALL
SELECT DATEADD(d, 1, pe_start_date) as dt
FROM #ENROLLEES s
WHERE DATEADD(d, 1, pe_start_date) <= '12/1/11')
The most obvious issue (and probably the one that causes the error message too) is the absence of the actual statement to which the last CTE is supposed to pertain. I presume it should be a SELECT statement, one that would combine the result set of the CTE with the data from the #ENROLLEES table.
And that's where another issue emerges.
You see, apart from the fact that a name that starts with a single # is hardly advisable for anything that is not a local temporary table (a CTE is not a table indeed), you've also chosen for your CTE a particular name that already belongs to an existing table (more precisely, to the already mentioned #ENROLLEES temporary table), and the one you are going to pull data from too. You should definitely not use an existing table's name for a CTE, or you will not be able to join it with the CTE due to the name conflict.
It also appears that, based on its code, the last CTE represents an unfinished implementation of the logic you say you want to add to the SP. I can suggest some idea, but before I go on I'd like you to realise that there are actually two different requests in your post. One is about finding the cause of the error message, the other is about code for a new logic. Generally you are probably better off separating such requests into distinct questions, and so you might be in this case as well.
Anyway, here's my suggestion:
build a complete list of dates you want to be accounted for in the result set (that's what the CTE will be used for);
left-join that list with the #ENROLLEES table to pick data for the existing dates and some defaults or NULLs for the non-existing ones.
It might be implemented like this:
… /* all your code up until the last WITH */
;
WITH cte AS (
SELECT CAST('7/1/11' AS date) AS dt
UNION ALL
SELECT DATEADD(d, 1, dt) as dt
FROM cte
WHERE dt < '12/1/11'
)
SELECT
cte.dt,
tmp.[Program code],
tmp.[program_name],
… /* other columns as necessary; you might also consider
enveloping some or all of the "tmp" columns in ISNULLs,
like in
ISNULL(tmp.[Program code], '(none)') AS [Program code]
to provide default values for absent data */
FROM cte
LEFT JOIN #ENROLLEES tmp ON cte.dt = tmp.pe_start_date
;