Trouble when using expression IN - expression

Use: db: HSQLDB, jdbctemplate.
I created tables:
<SELECTED_DATE ID="1" DATE_VALUE="2018-02-02 00:00:00.000000"/>
<SELECTED_DATE ID="2" DATE_VALUE="2018-02-03 00:00:00.000000"/>
<SELECTED_DATE ID="3" DATE_VALUE="2018-02-04 00:00:00.000000"/>
<SELECTED_DATE ID="4" DATE_VALUE="2018-02-05 00:00:00.000000"/>
<SELECTED_DATE ID="5" DATE_VALUE="2018-02-07 00:00:00.000000"/>
<SELECTED_DATE ID="6" DATE_VALUE="2018-02-08 00:00:00.000000"/>
How to use select * from SELECTED_DATE where DATE_VALUE in ( '2018-02-08', ... );
this causes an error: java.sql.SQLSyntaxErrorException: data type of expression is not boolean
or select * from SELECTED_DATE where DATE_VALUE IN ELEMENTS('2018-02-08', ...);
this causes an error: java.sql.SQLSyntaxErrorException: unexpected token: ELEMENTS required: (
but such select * from SELECTED_DATE where DATE_VALUE = ( '2018-02-08'); its work

Your date column is in fact a TIMESTAMP column.
For IN predicates, you need to declare the type of the values:
select * from SELECTED_DATE where DATE_VALUE in ( DATE'2018-02-02', DATE'2018-02-03');
The above works. If your SELECT statement does not still work, please report the complete statement.

Related

Oracle XML ORA-00978: nested group function without GROUP BY

I am trying to generate XML using Oracle's XML functions but I keep getting the ORA-00978: nested group function without GROUP BY error message.
I am new to XML and also Oracle's XML functions so it seems I am missing something major however when looking at examples online I can't understand what I am doing wrong.
SQL:
select
xmlelement("apiRequest",
xmlelement("orders",
xmlagg(
xmlelement("order",
xmlelement("no", orders.order_no),
xmlelement("date", orders.date),
xmlelement("orderItems",
xmlagg(
xmlelement("orderItem",
xmlelement("position", order_items.item_position)
)
)
)
)
)
)
)
as xml
from
...
Desired output:
<apiRequest>
<orders>
<order>
<no>1</no>
<date>04/03/2010</date>
<orderItems>
<orderItem>
<position>1</position>
</orderItem>
<orderItem>
<position>2</position>
</orderItem>
<orderItem>
<position>3</position>
</orderItem>
<orderItem>
<position>4</position>
</orderItem>
</orderItems>
</order>
<order>
<no>2</no>
<date>04/03/2010</date>
<orderItems>
<orderItem>
<position>1</position>
</orderItem>
<orderItem>
<position>2</position>
</orderItem>
<orderItem>
<position>3</position>
</orderItem>
<orderItem>
<position>4</position>
</orderItem>
</orderItems>
</order>
</orders>
</apiRequest>
When you do a nested aggregation, you need a GROUP BY clause. The first level of aggregation is at the GROUP BY level, then the result of that is aggregated again.
To illustrate, I used the ORDERS and ORDER_ITEMS tables from the OE schema that Oracle provides.
select
xmlelement("apiRequest",
xmlelement("orders",
xmlagg(
xmlelement("order",
xmlelement("no", order_id),
xmlelement("date", oe.orders.order_date),
xmlelement("orderItems",
xmlagg(
xmlelement("orderItem",
xmlelement("position", oe.order_items.line_item_id)
)
)
)
)
)
)
)
as xml
from oe.orders join oe.order_items using(order_id)
group by order_id, order_date;
The other answer uses a scalar subquery, which I would avoid in this case because it executes one recursive SQL for each order instead of simply joining.
You could put second xmlagg in a subquery, it gives desired result:
select
xmlelement("apiRequest",
xmlelement("orders",
xmlagg(
xmlelement("order",
xmlelement("no", orders.order_no),
xmlelement("date", orders.order_date),
xmlelement("orderItems",
(select xmlagg(
xmlelement("orderItem",
xmlelement("position", order_items.item_position)
)
)
from order_items where order_no = orders.order_no)
))))) as xml
from orders
dbfiddle

Oracle error in MyBatis XML Mapper file, but not in SQL Developer

I have a query in a MyBatis XML wrapper that results in a ORA-00904 invalid identifier. However, when I copy the statement shown in the log it runs.
The log message is
SQL: select /*+ parallel(AUTO) */ avg(DURATION) AVERAGE_SESSION_DURATION
from sc_report_new.sc_hub_session_activity schsa
inner join sc_hub_users schu on schsa.user_key=schu.user_key
inner join sc_hub_user_types schut on chut.user_type_id=schu.user_type_id
inner join sc_hub_content_master schcm on chcm.trace_id_key=schsa.hub_key
WHERE schsa.FISCAL_QUARTER_ID = '2020Q2'
Cause: java.sql.SQLSyntaxErrorException: ORA-00904: "SCHSA"."FISCAL_QUARTER_ID": invalid identifier
at org.apache.ibatis.exceptions.ExceptionFactory.wrapException(ExceptionFactory.java:30)
at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:149)
at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:140)
at org.apache.ibatis.session.defaults.DefaultSqlSession.selectOne(DefaultSqlSession.java:76)
The snippet of the mapper query is
<select id="getDashboardAverageSessionDuration"
resultType="int"
parameterType="com.mycompany.salesconnect.screport.model.AuthorizedHubRequest">
select /*+ parallel(AUTO) */
avg(DURATION) AVERAGE_SESSION_DURATION
from sc_report_new.sc_hub_session_activity schsa
inner join sc_hub_users schu
on schsa.user_key=schu.user_key
inner join sc_hub_user_types schut
on schut.user_type_id=schu.user_type_id
inner join sc_hub_content_master schcm
on schcm.trace_id_key=schsa.hub_key
<include refid="com.mycompany.salesconnect.screport.mapper.hubportfolio.Common.joinHubAuthorizations">
<property name="hubAuthorizations" value="hubAuthorizations"/>
</include>
<where>
<if test="hubRequestFilter.dateRangeSpecified">
schsa.time_stamp
BETWEEN to_date(#{hubRequestFilter.fromDate}, 'mm/dd/yyyy')
AND
to_date(#{hubRequestFilter.toDate}, 'mm/dd/yyyy')
</if>
<if test="!hubRequestFilter.dateRangeSpecified">
<if test="hubRequestFilter.quarterListByNameNotEmpty">
SCHSA.FISCAL_QUARTER_ID IN
<foreach item="quarterName" collection="hubRequestFilter.quarterListByName" open="(" close=")" separator=",">
<bind name="quarterId"
value="#com.mycompany.salesconnect.screport.dao.SCHubPortfolioUtil#getQuarterAsId(quarterName)"/>
#{quarterName}
</foreach>
</if>
<if test="hubRequestFilter.quarterListByIdNotEmpty">
SCHSA.FISCAL_QUARTER_ID IN
<foreach item="quarterId" collection="hubRequestFilter.quarterListById" open="(" close=")" separator=",">
#{quarterId}
</foreach>
</if>
</if>
<include refid="com.mycompany.salesconnect.screport.mapper.hubportfolio.Common.whereHubRequestFilter"><property name="hubRequestFilter" value="hubRequestFilter"></property></include>
<include refid="com.mycompany.salesconnect.screport.mapper.hubportfolio.Common.whereHubAuthorizations"><property name="hubAuthorizations" value="hubAuthorizations"></property></include>
</where>
</select>
I looked for non-printable characters in the XML and didn't see any. Stating what should be obvious, the SC_HUB_SESSION_ACTIVITY table has a FISCAL_QUARTER_ID field. Interestingly, if I choose another SCHSA column, it works. For some reason the system singles out this field for arbitrarily not working.
This was not an issue with MyBatis but rather not pointing to the same database as the SQL Developer that I was using.

Want to extract the a text from a tag

I have a column in a table where the data is stored in below format
<Server start>
<message tagid=" ">false</message>
<message tagid="34">no data found</message>
<message tagid=" ">false</message>
<Server stop>
Where I need to extract "no data found". Tried using regexp replace function but couldnot make it in a proper way.
Note: message tag id (number) can be of any length.
Query:
SELECT x.tagid,
x.message
FROM your_table t
CROSS JOIN
XMLTable(
'/Server/message'
PASSING XMLType(
REPLACE(
REPLACE( t.your_column, '<Server start>', '<Server>' ),
'<Server stop>',
'</Server>'
)
)
COLUMNS tagid VARCHAR2(100) PATH './#tagid',
message VARCHAR2(400) PATH './text()'
) x;
Output
TAGID MESSAGE
----- -------
false
34 no data found
false
If you just want the values where the message is no data found then add a WHERE clause at the end of the query:
WHERE x.message = 'no data found';
Try to build your query based on the following code. First converting your text to XML, then extract neccesary data by using XMLType.extract() function
with test_query as (select XMLType(replace(replace(s,'<Server stop>','</Server>'),'<Server start>','<Server>')) xml from
(select '<Server start>
<message tagid=" ">false</message>
<message tagid="34">no data found</message>
<message tagid=" ">false</message>
<Server stop>' as s from dual))
select
t.xml.extract('//message[position()=2]/text()') out
from test_query t;

xquery return Boolean if node exists at a certain location or not

I have XML similar to the following in a SQL 2008 database, stored in an XML field. I would like to return a true or false indication if a node exists in a specific section of the XML.
<root>
<node attribute1='value1' attribute2='value2'>
<sub1 name='ID' value="1" />
<sub2 name='project' value="abc" />
<sub3 name='Lead' value="John" />
</node>
<entry attribute1='value1' attribute2='value2'>
<message>start</message>
</entry>
<entry attribute1='value1' attribute2='value2'>
<attribute name='project' value='done'>
</entry>
<node attribute1='value1'>
<sub1 name='ID' value="2" />
<sub2 name='project' value="abc" />
<sub3 name='Lead' value="John" />
</node>
<entry attribute1='value1' attribute2='value2'>
<message>start</message>
</entry>
<node attribute1='value1'>
<sub1 name='ID' value="3" />
<sub2 name='project' value="abc" />
<sub3 name='Lead' value="John" />
</node>
<entry attribute1='value1' attribute2='value2'>
<message>start</message>
</entry>
<node attribute1='value1'>
<sub1 name='ID' value="4" />
<sub2 name='project' value="abc" />
<sub3 name='Lead' value="John" />
</node>
<entry attribute1='value1' attribute2='value2'>
<message>start</message>
</entry>
<entry attribute1='value1' attribute2='value2'>
<attribute name='project' value='done'>
</entry>
</root>
As you'll notice, the <attribute> node may or may not occur after a node with 'ID'. In this example, you can see it in the first and fourth "sections" for lack of a better term.
With the following table structure:
ID (PK)
EventID (FK)
RawXML (XML)
Created (datetime)
Here is an extract of the SQL/xQuery that I have so far:
WITH XMLNAMESPACES(
'http://www.w3.org/2001/XMLSchema-instance' as xsi,
),
t1 as(
SELECT distinct
x.EventId
, c.value ('(//node/sub[#name=''ID'']/#value)[1]', 'nvarchar(max)') as ID
, c.value ('(//node/sub[#name=''ID''][1][descendant::attribute/#name=''project''])[1]', 'nvarchar(max)' ) as Exists
FROM
Table1 x
CROSS APPLY
RawXML.nodes('./.') as t(c)
)
select distinct
t1.ID
, t1.Exists
from t1
I will be running the script 4 or more times (incrementing all of the singleton values before each run)
For the XML given, I need to end up with the following results after running the query 4 times:
(the values of the IDs will not be know so I can't use them in the query)
ID Exists
---- -------
1 true
2 false
3 false
4 true
With the SQL given, I didn't get any errors but it's taking forever (well over 45 minutes) and I haven't even let it finish yet. It really shouldn't take this long to parse the XML.
UPDATE: I limited my query to make sure it was only parsing one row (one XML file) and it finished in 57 seconds. However, I got a result of '0' for ID 1 and ID 2 when I should have had a '1' for ID 1.
And I'm sure most of you are aware that following-sibling, etc isn't supported by SQL Server so unfortunately that's not an option.
Just for reference, I've used this successfully to find the two instances of 'Project' but it ignores where in the xml they occur.:
c.value ('(//node[descendant::attribute/#name=''Project''])[1]', 'nvarchar(max)' ) as TrueFalse
So basically, I need to know if the node with name='Project' exists after a node with name='ID' BUT before the next instance of a node with name='ID'
You have some errors in your XML and judging by the query you use I also changed the sub nodes.
You can enumerate your ID and project nodes using row_number() and then check if the "next row" is a project node or a an ID row using regular SQL instead of XQuery.
-- Temp table to hold the extracted values from the XML
create table #C
(
rn int primary key,
ID int
);
-- Get the enumerated rows with ID.
-- project nodes will have NULL in ID
insert into #C
select row_number() over(order by T.N) as rn,
T.N.value('sub[#name = "ID"][1]/#value', 'int') as ID
from table1
cross apply RawXML.nodes('/root/*[sub/#name = "ID" or attribute/#name = "project"]') as T(N)
-- Get the ID's and check if the next row is a project node
select C1.ID,
case when exists (
select *
from #C as C2
where C1.rn + 1 = C2.rn and
C2.ID is null
)
then 1
else 0
end as [Exists]
from #C as C1
where C1.ID is not null;
drop table #C;
SQL Fiddle
You can do it without a temp table using a CTE instead but I suspect that the temp table version will be faster.
with C as
(
select row_number() over(order by T.N) as rn,
T.N.value('sub[#name = "ID"][1]/#value', 'int') as ID
from table1
cross apply RawXML.nodes('/root/*[sub/#name = "ID" or attribute/#name = "project"]') as T(N)
)
select C1.ID,
case when exists (
select *
from C as C2
where C1.rn + 1 = C2.rn and
C2.ID is null
)
then 1
else 0
end as [Exists]
from C as C1
where C1.ID is not null;
SQL Fiddle

Hibernate native SQL error

I am trying to execute sql native query using hibernate 3.3.2.GA.
I have following query.
session.createSQLQuery("SELECT {dept1.*}, {dept2.*} FROM Dept d1, Dept d2 WHERE d1.deptId = d2.deptId").
addEntity("dept1",com.test.pojo.Dept.class).
addEntity("dept2",com.test.pojo.Dept.class).
list();
Mapping file for Dept class is
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.test.pojo.Dept">
<id column="deptId" name="deptId" type="long">
<generator class="native"/>
</id>
<version name="version" access="field" column="version"></version>
<property name="deptName" type="string" column="deptName"/>
<set name="emps" cascade="all" inverse="true">
<key column="deptId"></key>
<one-to-many class="com.test.pojo.Emp"/>
</set>
</class>
</hibernate-mapping>
But why I get following error? It is converting my query to
SELECT dept1.**deptId as deptId1_0_, **dept1.**version as
version1_0_, **dept1.**deptName as deptName1_0_, **dept2.**deptId as
deptId1_1_, **dept2.**version as version1_1_, **dept2.**deptName as
deptName1_1_ **FROM Dept d1, Dept d2 WHERE d1.deptId = d2.deptId.
Hibernate: SELECT dept1.deptId as deptId1_0_, dept1.version as
version1_0_, dept1.deptName as deptName1_0_, dept2.deptId as
deptId1_1_, dept2.version as version1_1_, dept2.deptName as
deptName1_1_ FROM Dept d1, Dept d2 WHERE d1.deptId = d2.deptId
20:43:41,109 WARN JDBCExceptionReporter:100 - SQL Error: 904,
SQLState: 42000 20:43:41,109 ERROR JDBCExceptionReporter:101 -
ORA-00904: "DEPT2"."DEPTNAME": invalid identifier
Exception in thread "main" org.hibernate.exception.SQLGrammarException: could not execute query
at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:90)
at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:66)
at org.hibernate.loader.Loader.doList(Loader.java:2235)
at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2129)
at org.hibernate.loader.Loader.list(Loader.java:2124)
at org.hibernate.loader.custom.CustomLoader.list(CustomLoader.java:312)
at org.hibernate.impl.SessionImpl.listCustomQuery(SessionImpl.java:1723)
at org.hibernate.impl.AbstractSessionImpl.list(AbstractSessionImpl.java:165)
at org.hibernate.impl.SQLQueryImpl.list(SQLQueryImpl.java:175)
at com.test.test.Test1.main(Test1.java:96)
Caused by: java.sql.SQLException: ORA-00904: "DEPT2"."DEPTNAME": invalid identifier
at oracle.jdbc.dbaccess.DBError.throwSqlException(DBError.java:134)
at oracle.jdbc.ttc7.TTIoer.processError(TTIoer.java:289)
at oracle.jdbc.ttc7.Oall7.receive(Oall7.java:590)
at oracle.jdbc.ttc7.TTC7Protocol.doOall7(TTC7Protocol.java:1973)
at oracle.jdbc.ttc7.TTC7Protocol.parseExecuteDescribe(TTC7Protocol.java:850)
at oracle.jdbc.driver.OracleStatement.doExecuteQuery(OracleStatement.java:2599)
at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:2963)
at oracle.jdbc.driver.OraclePreparedStatement.executeUpdate(OraclePreparedStatement.java:658)
at oracle.jdbc.driver.OraclePreparedStatement.executeQuery(OraclePreparedStatement.java:584)
at org.hibernate.jdbc.AbstractBatcher.getResultSet(AbstractBatcher.java:208)
at org.hibernate.loader.Loader.getResultSet(Loader.java:1812)
at org.hibernate.loader.Loader.doQuery(Loader.java:697)
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:259)
at org.hibernate.loader.Loader.doList(Loader.java:2232)
... 7 more
It should be
session.createSQLQuery(
"SELECT {dept1.*}, {dept2.*} FROM Dept dept1, Dept dept2 WHERE dept1.deptId = dept2.deptId")
.addEntity("dept1",com.test.pojo.Dept.class)
.addEntity("dept2",com.test.pojo.Dept.class)
.list();
If you was misled by the documentation (18.1.4. Returning multiple entities), there is a bug there (HHH-2976), feel free to vote for it.
Try Google with the ORA-XXX codes. From http://www.dba-oracle.com/t_ora_00904_string_invalid_identifier.htm
Question: I am running a SQL
statement and I get a SQL*Plus error
ORA-00904 invalid identifier.
Answer: When ORA-00904 occurs, you
must enter a valid column name as it
is either missing or the one entered
is invalid. The "invalid identifier"
most common happens when you are
referencing an invalid alias in a
select statement. The Oracle docs
note this on the ORA-00904 error:

Resources