JDOQL Correlated Subquery - Bad SQL
Hi,
When I execute a JDOQL correlated subquery, the generated SQL is either
invalid or incorrect. Exactly what happens depends on the exact query, and
on the target database type, but I believe it all stems from the same
problem, which has to do with table aliasing.
If you need further details to reproduce this, please let me know. I'll be
glad to help in any way I can to get this situation remedied quickly, as I
am depending on this functionality. I have a test application to
demonstrate the problem.
I'm using Kodo 3.3.3 and application identity.
Paul Mogren
CommerceHub
For the record, this is in part due to a bug in Kodo's SQL92 joining.
See http://bugzilla.solarmetric.com/show_bug.cgi?id=1156
-Patrick
Paul Mogren wrote:
Certainly... Here's a simple example using Microsoft's JDBC Driver for SQL
Server 2000, and kodo.jdbc.sql.SQLServerDictionary, which produces invalid
SQL.
The query:
pm.newQuery(Container.class,
"(select from Entry entry where entries.contains(entry) &&
entry.containedId != 1).isEmpty()");
The classes:
class Contained {
private int id; //pk
class Container {
private int id; //pk
private Set entries = new HashSet(); //<Entry>
class Entry {
private int containerId; //pk
private int containedId; //pk
private Container container; //persistent-redundant
private Contained contained; //persistent-redundant
The result:
Incorrect syntax near the keyword 'WHERE'. {prepstmnt 31598780 SELECT
t0.container_id, t0.lock FROM WHERE (NOT EXISTS (SELECT DISTINCT
t2.contained_id, t2.container_id FROM dbo.entry t2 WHERE (t1.contained_id
= t2.contained_id AND t1.container_id = t2.container_id AND
t2.contained_id <> ?) AND t0.container_id = t1.container_id))
[params=(int) 1]} [code=156, state=HY000]
Patrick Linskey wrote:
Hi Paul,
Kodo's correlated subquery support does have some known limitations. Can
you post a sample JDOQL statement + corresponding SQL statement?
-Patrick
Paul Mogren wrote:
Hi,
When I execute a JDOQL correlated subquery, the generated SQL is either
invalid or incorrect. Exactly what happens depends on the exact query, and
on the target database type, but I believe it all stems from the same
problem, which has to do with table aliasing.
If you need further details to reproduce this, please let me know. I'll be
glad to help in any way I can to get this situation remedied quickly, as I
am depending on this functionality. I have a test application to
demonstrate the problem.
I'm using Kodo 3.3.3 and application identity.
Paul Mogren
CommerceHub
Similar Messages
-
SQL Bug in "Minus" in correlated subquery presence of index
(Oracle Database 11g Release 11.2.0.1.0)
Below, there is a small example that shows the bug. Further below,
there are some more comments.
drop table Country;
create table Country
(code VARCHAR2(4) constraint countrykey PRIMARY KEY,
name VARCHAR2(35));
-- if the key constraint is not given, the bug does not occur
drop table City;
create table City
(name VARCHAR2(35),
country VARCHAR2(4),
population number);
drop table Locatedon;
create table Locatedon
(city VARCHAR2(35),
country VARCHAR2(4),
island VARCHAR2(35));
insert into country values('E','Spain');
insert into country values('F','France');
insert into country values('S','Sweden');
insert into country values('GB','Sweden');
insert into city values('Ajaccio','F',53500);
insert into city values('Paris','F',2152423);
insert into city values('Palma','E',322008);
insert into city values('Madrid','E',3041101);
insert into city values('Stockholm','S',711119);
insert into city values('London','GB',6967500);
insert into locatedon values('Ajaccio','F','Corse');
insert into locatedon values('Palma','E','Mallorca');
insert into locatedon values('London','GB','Great Britain');
-- all countries that have a city that is not located on
-- some island: should be E, F, S.
Select c.name
From country c
Where exists
((Select name
From city
Where city.country=c.code)
minus
(Select city
From locatedon
Where locatedon.country=c.code)
-- wrong answer: only Sweden; Spain and France not in the answer!
select distinct country from
((Select name, country
From city)
minus
(Select city, country
From locatedon)
-- correct answer: E, F, S
Comments:
The bug has been found by students in our SQL course.
Using a larger database from that course, the bug can be reproduced
(same queries as above) at
http://www.semwebtech.org/sqlfrontend/
(wrong: 142 answers, correct: 154 answers)
During reducing it to a simple sample, there were some interesting
observations: trying with smaller and simpler tables (without the keys)
and synthetic data, the bug did not occur immediately. When
restating the query after about one day, the bug occurred. Obviously,
Oracle creates some index on its own in course of its internal
optimization that (or more exactly, its usage) exhibits the bug. The
query plan (showed in SQL Developer) was the same before and after.
WolfgangThere's a typo in the test data - GB should presumably not be in Sweden. However....
the bug did not occur immediatelyIt's possible. But what would have almost certainly happened is that the execution plan DID change at some point. There are various reasons why it might not be immediate.
Obviously, Oracle creates some index on its own in course of its internal optimizationFar from obvious, what are you on about?
The query plan was the same before and afterBet you it wasn't.
A clear illustration of the issue and indication that it must be a bug is below.
Simply by hinting a different access method, we can change the result. Therefore, bug.
See [url http://support.oracle.com]Oracle Support and search for "wrong results".
Please raise with Oracle Support to get confirmation of bug.
There have been so many wrong results bugs recently, it's getting ridiculous.
It's a real issue, IMHO.
If you can't trust the DB to get your data right....
Note that the query plan is very much NOT the same and it is the difference in query plan which s that is the root cause of the bug.
SQL> select * from v$version;
BANNER
Oracle Database 11g Enterprise Edition Release 11.2.0.2.0 - 64bit Production
PL/SQL Release 11.2.0.2.0 - Production
CORE 11.2.0.2.0 Production
TNS for Linux: Version 11.2.0.2.0 - Production
NLSRTL Version 11.2.0.2.0 - Production
SQL> SELECT c.name
2 FROM country1 c
3 WHERE exists ((SELECT name
4 FROM city1
5 WHERE city1.country=c.code)
6 MINUS
7 (SELECT city
8 FROM locatedon1
9 WHERE locatedon1.country=c.code));
NAME
Sweden
SQL> SELECT /*+ full(c) */
2 c.name
3 FROM country1 c
4 WHERE exists ((SELECT name
5 FROM city1
6 WHERE city1.country=c.code)
7 MINUS
8 (SELECT city
9 FROM locatedon1
10 WHERE locatedon1.country=c.code));
NAME
Spain
France
Sweden
SQL> explain plan for
2 SELECT c.name
3 FROM country1 c
4 WHERE exists ((SELECT name
5 FROM city1
6 WHERE city1.country=c.code)
7 MINUS
8 (SELECT city
9 FROM locatedon1
10 WHERE locatedon1.country=c.code));
Explained.
SQL> select * from table(dbms_xplan.display);
PLAN_TABLE_OUTPUT
Plan hash value: 156929629
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
| 0 | SELECT STATEMENT | | 1 | 27 | 12 (25)| 00:00:01 |
| 1 | NESTED LOOPS | | | | | |
| 2 | NESTED LOOPS | | 1 | 27 | 12 (25)| 00:00:01 |
| 3 | VIEW | VW_SQ_1 | 6 | 24 | 10 (20)| 00:00:01 |
| 4 | MINUS | | | | | |
| 5 | SORT UNIQUE | | 6 | 138 | | |
| 6 | TABLE ACCESS FULL | CITY1 | 6 | 138 | 4 (0)| 00:00:01 |
| 7 | SORT UNIQUE | | 3 | 69 | | |
| 8 | TABLE ACCESS FULL | LOCATEDON1 | 3 | 69 | 4 (0)| 00:00:01 |
|* 9 | INDEX UNIQUE SCAN | COUNTRYKEY | 1 | | 0 (0)| 00:00:01 |
| 10 | TABLE ACCESS BY INDEX ROWID| COUNTRY1 | 1 | 23 | 1 (0)| 00:00:01 |
Predicate Information (identified by operation id):
9 - access("VW_COL_1"="C"."CODE")
Note
- dynamic sampling used for this statement (level=4)
26 rows selected.
SQL> explain plan for
2 SELECT /*+ full(c) */
3 c.name
4 FROM country1 c
5 WHERE exists ((SELECT name
6 FROM city1
7 WHERE city1.country=c.code)
8 MINUS
9 (SELECT city
10 FROM locatedon1
11 WHERE locatedon1.country=c.code));
Explained.
SQL> select * from table(dbms_xplan.display);
PLAN_TABLE_OUTPUT
Plan hash value: 1378726376
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
| 0 | SELECT STATEMENT | | 1 | 23 | 14 (15)| 00:00:01 |
|* 1 | FILTER | | | | | |
| 2 | TABLE ACCESS FULL | COUNTRY1 | 4 | 92 | 4 (0)| 00:00:01 |
| 3 | MINUS | | | | | |
| 4 | SORT UNIQUE | | 1 | 23 | 5 (20)| 00:00:01 |
|* 5 | TABLE ACCESS FULL| CITY1 | 1 | 23 | 4 (0)| 00:00:01 |
| 6 | SORT UNIQUE | | 1 | 23 | 5 (20)| 00:00:01 |
|* 7 | TABLE ACCESS FULL| LOCATEDON1 | 1 | 23 | 4 (0)| 00:00:01 |
Predicate Information (identified by operation id):
1 - filter( EXISTS ( (SELECT "NAME" FROM "CITY1" "CITY1" WHERE
"CITY1"."COUNTRY"=:B1)MINUS (SELECT "CITY" FROM "LOCATEDON1" "LOCATEDON1"
WHERE "LOCATEDON1"."COUNTRY"=:B2)))
5 - filter("CITY1"."COUNTRY"=:B1)
7 - filter("LOCATEDON1"."COUNTRY"=:B1)
Note
- dynamic sampling used for this statement (level=4)
27 rows selected.Just to show that it's related to query transformation:
SQL> SELECT /*+
2 no_query_transformation
3 */
4 c.name
5 FROM country1 c
6 WHERE exists ((SELECT name
7 FROM city1
8 WHERE city1.country=c.code)
9 MINUS
10 (SELECT city
11 FROM locatedon1
12 WHERE locatedon1.country=c.code));
NAME
Spain
France
Sweden
SQL> Edited by: Dom Brooks on Jun 30, 2011 2:50 PM -
Top n Analysis using correlated subquery
Please explain this query. It is doing top n analysis using correlated subquery. I need explaination of execution of this query.
Select distinct a.sal
From emp a
where 1=(select count ( distinct b.sal) from emp b
where a.sal <=b.sal)
Thanks in advanceTry breaking the query down and rewriting it in order to follow the logic;
SQL> --
SQL> -- Start by getting each salary from emp along with a count of all salaries in emp
SQL> --
SQL> select a.sal,
(select count (distinct b.sal) from scott.emp b ) count_sal
from scott.emp a
order by 1 desc
SAL COUNT_SAL
5000 12
3000 12
3000 12
2975 12
2850 12
2450 12
1600 12
1500 12
1300 12
1250 12
1250 12
1100 12
950 12
800 12
14 rows selected.
SQL> --
SQL> --Add a condition to the count for only salaries below or equal to the current salarySQL> --
SQL> select a.sal,
(select count (distinct b.sal) from scott.emp b where a.sal <=b.sal) rank_sal
from scott.emp a
order by 1 desc
SAL RANK_SAL
5000 1
3000 2
3000 2
2975 3
2850 4
2450 5
1600 6
1500 7
1300 8
1250 9
1250 9
1100 10
950 11
800 12
14 rows selected.
SQL> --
SQL> -- Add a condition to only pick the nth highest salary
SQL> --
SQL> select a.sal,
(select count (distinct b.sal) from scott.emp b where a.sal <=b.sal) rank_sal
from scott.emp a
where (select count (distinct b.sal) from scott.emp b where a.sal <=b.sal) = 4
SAL RANK_SAL
2850 4
1 row selected.Hope this helps. -
OBIEE consistently producing very very bad SQL
Hi,
We need some advice, or would like to know if people have had similar experiences. Here is our issue.
Users running reports and filtering data in presentation layer of OBIEE are seeing the OBIEE generate the SQL and sends it to the database.
This SQL which is auto generated by the OBIEE server is extremely costly. We are not whu OBIEE produces such bad sql - anyone have same problem?
When we look at explains, we see that most costly operations are when HASH operations are used. This is consistent throughout all OBIEE generated SQL.
As the SQL is of ad hock nature we do not use SPB's etc.
We are puzzled and are not sure where to start w.r.t troubleshooting.
Please help.Dear guru.
Let me know what's may be wrong ?
My post is closely related to bad SQL thread.
Shortly speaking, I'd like to discuss multiple star problem.
So, Oracle Business Intelligence 11.1.1.6.0
I have three fact table A,B,C joined to common link table D ( look as dimension in Administrator )
A and B have inner join with D, while C has left outer join to D ( actually outer join defined only in BMM cause don't see how set outer join on physical layer for C ).
The matter is in generated SQL query which is broken, i.e. can't be compiled in Oracle DB.
Let me give broken piece of generated SQL.
As you can see, the subquery has reference to table T69242 in WHERE, but no such table in FROM section:
SACOMMON821644 AS
(SELECT
/*+ MATERIALIZE */
DISTINCT T68993.NAME AS c1,
T69266.DISTRICT2 AS c2,
CASE
WHEN T68993.DEPARTMENTID IN
(SELECT D1.c1 AS c1 FROM SASUBWITH820608 D1
THEN 1
ELSE 0
END AS c3,
CASE
WHEN T69266.OKATO_KOD IN
(SELECT D1.c1 AS c1
FROM SASUBWITH820633 D1
THEN 1
ELSE 0
END AS c4,
T68993.DEPARTMENTID AS c5,
T69266.OKATO_KOD AS c6,
T68993.PARENT AS c7,
T69266.PARENT_OKATO_KOD AS c8
FROM BI_MSK_DISTRICTS_STAT_HIER T69233
MOS_DISTRICTS_STAT T69266
BI_DEPARTMENTS_MFC T68993
BI_MFC_HIER T69068
DEP_OPERATORS_CNT T69220
INCIDENTS T69648
MOS_DISTRICT_POPULATION T69410
WHERE ( T69233.MEMBER_KEY = T69410.OKATO_KOD
AND T68993.DEPARTMENTID = T69068.ANCESTOR_KEY
AND T69068.MEMBER_KEY = T69220.DEPARTMENTID
AND T69220.DEPARTMENTID = T69242.DEPARTMENTID*
AND T69233.ANCESTOR_KEY = T69266.OKATO_KOD
AND T69242.OKATO_KOD* = T69410.OKATO_KOD
AND T68993.DEPARTMENTID IN
(SELECT D1.c1 AS c1 FROM SASUBWITH820658 D1
AND T69266.OKATO_KOD IN
(SELECT D1.c1 AS c1 FROM SASUBWITH820683 D1
Meanwhile in aggregation subquery of that generated SQL we have requred table
SACOMMON821667 AS
(SELECT
/*+ MATERIALIZE */
TRUNC(SUM( DISTINCT T69220.OPER_TOTAL)) AS c9,
T68993.DEPARTMENTID AS c10,
T68993.PARENT AS c11,
T69266.OKATO_KOD AS c12,
T69266.PARENT_OKATO_KOD AS c13,
SUM( DISTINCT T69410.POPUL_SIZE) AS c14,
SUM(T69648.TOTAL / NULLIF( T69242.OKATO_COUNT, 0)) AS c15
FROM BI_MSK_DISTRICTS_STAT_HIER T69233
MOS_DISTRICTS_STAT T69266
BI_DEPARTMENTS_MFC T68993
BI_MFC_HIER T69068
DEP_OPERATORS_CNT T69220
MFC_ADDRESSOKATO T69242*
LEFT OUTER JOIN INCIDENTS T69648
ON T69242.DEPARTMENTID = T69648.DEPARTMENTIDFROM,
MOS_DISTRICT_POPULATION T69410
WHERE ( T69242.OKATO_KOD = T69410.OKATO_KOD
AND T69233.ANCESTOR_KEY = T69266.OKATO_KOD
AND T69233.MEMBER_KEY = T69410.OKATO_KOD
AND T69220.DEPARTMENTID = T69242.DEPARTMENTID
AND T68993.DEPARTMENTID = T69068.ANCESTOR_KEY
AND T69068.MEMBER_KEY = T69220.DEPARTMENTID
AND T68993.DEPARTMENTID IN
(SELECT D1.c1 AS c1 FROM SASUBWITH820658 D1
AND T69266.OKATO_KOD IN
(SELECT D1.c1 AS c1 FROM SASUBWITH820683 D1
GROUP BY T68993.DEPARTMENTID,
T68993.PARENT,
T69266.OKATO_KOD,
T69266.PARENT_OKATO_KOD
And it's time to show Consistency Check results in Administrator.
There is no errors, but
WARNINGS:
Business Model Сводная таблица:
[39008] Logical dimension table A_MFC_ADDRESSOKATO has a source A_MFC_ADDRESSOKATO that does not join to any fact source.
[39020] Logical table source "Сводная таблица"."FCT Incidents"."A_Incidents": No path has been found to link all tables. There is no link between the set ( 'A_DEP_OPERATORS_CNT', 'A_MFC_ADDRESSOKATO', 'A_MOS_DISTRICT_POPULATION' ) and the set ( 'A_Incidents' ).
[39020] Logical table source "Сводная таблица"."A_DEP_OPERATORS_CNT"."A_DEP_OPERATORS_CNT ": No path has been found to link all tables. There is no link between the set ( ) and the set ( ).
[39020] Logical table source "Сводная таблица"."A_MOS_DISTRICT_POPULATION"."A_MOS_DISTRICT_POPULATION": No path has been found to link all tables. There is no link between the set ( ) and the set ( ).
I wonder, how that link can be realized, when fact tables already have joins to common dim A_MFC_ADDRESSOKATO.
Should I create Logical Dimmension for A_MFC_ADDRESSOKATO while it is actually bridge table in terms of 10G ?
Besides, as we can see from query, A B and C have its own dims.
So, finally as a result in Answers we have
ORA-00904: "T69242"."OKATO_KOD": invalid identifier at OCI call OCIStmtExecute
It should be mentioned that error is appeared only when I put measure from A_Incidents (C alias) on analys in Answers, till that all worked correctly, i.e. A,B joined successfully to D
and SQL query gave desired result.
Any suggestion on issue are greately appreciated.
Sorry for unformatted SQL, still don't know how to do it.
Sorry for the post as reply cause I don't see how create new thread.
Hope, my explanation was clear. -
How does oracle execute a correlated subquery .... some confusion
How does oracle 10g execute a correlated subquery?
I read some articles online & i am a little confused.
example:
select * from emp e
where e.deptno in (select d.deptno from dept d
where e.deptno = d.deptno);
My questions .......
1.In the above example, does oracle read the entire outer table first and then run the inner query using the rows returned by the outer query?
I read in some articles that they execute simultaneously.
How does this work?
2.Should the inner query have lesser amount of rows compared to the outer query for a good performance?
3.Can every correlated subquery be converted to a join and if so which one to use?
Truly appreciate any inputs on how oracle executes it at the backend.
Thanks in advance.user10541890 wrote:
How does oracle 10g execute a correlated subquery?
I read some articles online & i am a little confused.
example:
select * from emp e
where e.deptno in (select d.deptno from dept d
where e.deptno = d.deptno);
My questions .......
1.In the above example, does oracle read the entire outer table first and then run the inner query using the rows returned by the outer query?
I read in some articles that they execute simultaneously.
How does this work?SQL is not a procedural language. SQL code specifies what the system sill do, not how the system wlll do it; that's entirely up to the system.
What does it matter to you whether the two are done together, or if one is completed before the other begins?
The system will probably choose to run ucorellated subqueiris only once, and correlated queries multiple times as needed.
2.Should the inner query have lesser amount of rows compared to the outer query for a good performance?That usually doesn't matter.
It some cases, you may want to consider whether the subquery is correlated or not. If the subquery is very costly, and produces, say, 1 million rows, but you know the main query will only produce about 5 rows, then you may want to do a correlated subquery rather than an uncorrelated one.
3.Can every correlated subquery be converted to a join and if so which one to use?I believe so.
Use whichever is easier to code and debug. That will change depnding on the data and the requirements.
If performance is an issue, try different ways. Usually, where I've noticed a big difference, join was fastest.
By the way, it's unusual to have a correlated IN-subquery.
Usually IN-subqueris are uncorrelated, like this:
select *
from emp e
where e.deptno in ( select d.deptno
from dept d
);(This and the queries below produce the same resutls as your original query.)
Correlated subqueries are usually used for scalar subqueries or EXISTS subqueries, like this:
select *
from emp e
where EXISTS ( select d.deptno
from dept d
where e.deptno = d.deptno
);To do the same thing with a join:
select e.*
from emp e
join dept d on e.deptno = d.deptno
;assuming dept.deptno is unique. -
Bad SQL from 2.3.4 (and 2.3.2)
Hi guys,
In the Maine Lighthouse Rental app for my book, there are a total of 48 Rental records. To start
with, all rentals are available. Mary reserves one rental. Subsequently a search for all of Mary's
reservations and all available records, returns 95 rental references in the result collection
instead of 48. The problem arises from bad sql generated by Kodo 2.3.2 and 2.3.4.
This particular query can be fixed in two ways, but I'm not sure about the general mapping issues.
One, SELECT DISTINCT will fix it. Two, dropping the CUSTOMERX table from the query and changing the
first AND clause from:
WHERE (((t1.JDOIDX = 1351 AND t0.CUSTOMERX = t1.JDOIDX)
OR (t0.CUSTOMERX IS NULL))
to
WHERE (t0.CUSTOMERX = 1351
OR t0.CUSTOMERX IS NULL)
Code and generated SQL are below.
Hope this helps.
David Ezzio
---- query setup -------------
// set up query for customer's rentals and available rentals
Extent extent = pm.getExtent(Rental.class, false);
queryCustomerAndAvailableRentals = pm.newQuery(extent, "customer == c || customer == null");
queryCustomerAndAvailableRentals.declareParameters("Customer c");
queryCustomerAndAvailableRentals.setOrdering("week.startDate ascending, lighthouse.name ascending");
----- generated SQL -------
[ C:1923370; S:1238221; T:700575; D:10/22/02 3:48 PM ]
SELECT
t0.JDOIDX,
t0.JDOCLASSX,
t0.JDOLOCKX,
t0.CUSTOMERX,
t0.LIGHTHOUSEX,
t0.PRICEX,
t0.WEEKX,
t2.STARTDATEX,
t3.NAMEX
FROM
CUSTOMERX t1,
LIGHTHOUSEX t3,
RENTALX t0,
WEEKX t2
WHERE (((t1.JDOIDX = 1351 AND t0.CUSTOMERX = t1.JDOIDX)
OR (t0.CUSTOMERX IS NULL))
AND t0.LIGHTHOUSEX = t3.JDOIDX
AND t0.WEEKX = t2.JDOIDX)
ORDER BY
t2.STARTDATEX ASC,
t3.NAMEX ASCSQL*Net 2.3.4 was shipped along 8.0 products:
* SQL*Plus
* ORACLE NET8 PRODUCTS
* ORACLE NETWORKING PRODUCTS (SQL*NET 2.3.4)
* ORACLE 8 JDBC DRIVERS
This is not supported to connect against a 10g database. The last valid combination was 8.0.6 vs 9.2.0
~ Madrid. -
3.0.0RC2 MappingTool producing bad SQL
It looks like <jdbc-field-map type="many-many" table="TestServiceKeyArray"
element-column
..pk="keyArray" ref-column.pk="parent" order-column="seqno"/> is producing
bad SQL through MappingTool. It gives the following exception when run as
"kodo.jdbc.meta.MappingTool -action buildSchema ..."
It looks like the "seqno" order-column is of type "OTHER", which is not
correct.
Exception in thread "main" kodo.util.FatalException:
com.solarmetric.jdbc.ReportingSQLException: Syntax error or access
violation, message from server: "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 'OTHER)' at line 1" {stmnt 30301818: CREATE TABLE
TestServiceKeyArray (keyArray BIGINT, parent VARCHAR(255), seqno OTHER)}
[code=1064, state=42000]
NestedThrowables:
com.solarmetric.jdbc.ReportingSQLException: Syntax error or access
violation, message from server: "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 'OTHER)' at line 1" {stmnt 30301818: CREATE TABLE
TestServiceKeyArray (keyArray BIGINT, parent VARCHAR(255), seqno OTHER)}
[code=1064, state=42000]
at kodo.jdbc.meta.MappingTool.record(MappingTool.java:431)
at kodo.jdbc.meta.MappingTool.run(MappingTool.java:832)
at kodo.jdbc.meta.MappingTool.main(MappingTool.java:729)
Caused by: com.solarmetric.jdbc.ReportingSQLException: Syntax error or
access violation, message from server: "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 'OTHER)' at line 1" {stmnt 30301818: CREATE
TABLE TestServiceKeyArray (keyArray BIGINT, parent VARCHAR(255), seqno
OTHER)} [code=1064, state=42000]
at
com.solarmetric.jdbc.LoggingConnectionDecorator.wrap(LoggingConnectionDecora
tor.java:67)
at
com.solarmetric.jdbc.LoggingConnectionDecorator.access$400(LoggingConnection
Decorator.java:19)
at
com.solarmetric.jdbc.LoggingConnectionDecorator$LoggingConnection$LoggingSta
tement.executeUpdate(LoggingConnectionDecorator.java:506)
at kodo.jdbc.schema.SchemaTool.executeSQL(SchemaTool.java:1042)
at kodo.jdbc.schema.SchemaTool.createTable(SchemaTool.java:803)
at kodo.jdbc.schema.SchemaTool.add(SchemaTool.java:334)
at kodo.jdbc.schema.SchemaTool.add(SchemaTool.java:186)
at kodo.jdbc.meta.MappingTool.record(MappingTool.java:364)
... 2 moreI'm using mysql 4.0.15 and mysql connector (jdbc driver) 3.0.9.
Ben
"Stephen Kim" <[email protected]> wrote in message
news:[email protected]...
What version of MySQL and driver are you using?
Ben Eng wrote:
It looks like <jdbc-field-map type="many-many"
table="TestServiceKeyArray"
element-column
.pk="keyArray" ref-column.pk="parent" order-column="seqno"/> isproducing
bad SQL through MappingTool. It gives the following exception when runas
"kodo.jdbc.meta.MappingTool -action buildSchema ..."
It looks like the "seqno" order-column is of type "OTHER", which is not
correct.
Exception in thread "main" kodo.util.FatalException:
com.solarmetric.jdbc.ReportingSQLException: Syntax error or access
violation, message from server: "You have an error in your SQL syntax.
Check the manual that corresponds to your MySQL server version for theright
syntax to use near 'OTHER)' at line 1" {stmnt 30301818: CREATE TABLE
TestServiceKeyArray (keyArray BIGINT, parent VARCHAR(255), seqno OTHER)}
[code=1064, state=42000]
NestedThrowables:
com.solarmetric.jdbc.ReportingSQLException: Syntax error or access
violation, message from server: "You have an error in your SQL syntax.
Check the manual that corresponds to your MySQL server version for theright
syntax to use near 'OTHER)' at line 1" {stmnt 30301818: CREATE TABLE
TestServiceKeyArray (keyArray BIGINT, parent VARCHAR(255), seqno OTHER)}
[code=1064, state=42000]
at kodo.jdbc.meta.MappingTool.record(MappingTool.java:431)
at kodo.jdbc.meta.MappingTool.run(MappingTool.java:832)
at kodo.jdbc.meta.MappingTool.main(MappingTool.java:729)
Caused by: com.solarmetric.jdbc.ReportingSQLException: Syntax error or
access violation, message from server: "You have an error in your SQL
syntax. Check the manual that corresponds to your MySQL server versionfor
the right syntax to use near 'OTHER)' at line 1" {stmnt 30301818: CREATE
TABLE TestServiceKeyArray (keyArray BIGINT, parent VARCHAR(255), seqno
OTHER)} [code=1064, state=42000]
at
com.solarmetric.jdbc.LoggingConnectionDecorator.wrap(LoggingConnectionDecora
tor.java:67)
at
com.solarmetric.jdbc.LoggingConnectionDecorator.access$400(LoggingConnection
Decorator.java:19)
at
com.solarmetric.jdbc.LoggingConnectionDecorator$LoggingConnection$LoggingSta
tement.executeUpdate(LoggingConnectionDecorator.java:506)
at kodo.jdbc.schema.SchemaTool.executeSQL(SchemaTool.java:1042)
at kodo.jdbc.schema.SchemaTool.createTable(SchemaTool.java:803)
at kodo.jdbc.schema.SchemaTool.add(SchemaTool.java:334)
at kodo.jdbc.schema.SchemaTool.add(SchemaTool.java:186)
at kodo.jdbc.meta.MappingTool.record(MappingTool.java:364)
... 2 more
Steve Kim
[email protected]
SolarMetric Inc.
http://www.solarmetric.com -
Performance of using a Select For Update vs a correlated subquery
I was wondering wether or not it is more effecient to use the
Select ... For Update (with a cursor etc.) versus a correlated
subquery.
I can accomplish the same thing with either however performance
at our site is an issue.Use select for update cursor as that is faster as it updates
based on the rowid. One thing to keep in mind is that rowid is
session specific and the rows to be updated get locked so that
nobody else can update them till the lock is released. I have
had very good performance results with these cursors.
Good luck !
Sudha -
HashMap err --- Sql Exception - bad sql (pls see code)
Hi
//Query A
ResultSet resultSet = statement.executeQuery("select sno,rank from school");
BufferedWriter writeout = new BufferedWriter(new FileWriter(EDU, false));
while(resultSet.next()){
sno = resultSet.getString(1);
rank= resultSet.getString(2);
if("25".equals(rank)) {
// When the rank value is 25 , i want the hashA to have a key value pair in it , with value as 25 .
hashA.put(resultSet.getString(1),resultSet.getString(2)); /// ?? Sometimes the hashA contains key but for that key the value it contains is null
//Query B
resultSet = statement.executeQuery("select busno , driverno from License");
BufferedWriter writeFlat = new BufferedWriter(new FileWriter(OUT, false));
while(resultSet.next()){
busno = resultSet.getString(1);
driverno = resultSet.getString(2);
String rankOfB;
rankOfB = hashA.get(resultSet.getString(1)); // SO when i want to get the value it is giving an error SQL Exception - bad Sql . How to make this code work ,
System.out.println("The value of Rank is : "+rankOfB); // and when i get a value which is null from hashA , it is giving an error ... PLS HELP
writeFlat.close();
resultSet.close();
}catch (ClassNotFoundException classNotFound) {
System.out.println("Driver not Found"+classNotFound.getMessage());
} catch (SQLException sqlException) {
System.out.println("SQL Exception - bad sql");
System.out.println(sqlException.getMessage());
} catch (IOException e) {
e.printStackTrace();
Thank U in advance ...you cannot read a column twice within the same row
this is the part form javadoc
The ResultSet interface provides getter methods (getBoolean, getLong, and so on) for retrieving column values from the current row. Values can be retrieved using either the index number of the column or the name of the column. In general, using the column index will be more efficient. Columns are numbered from 1. For maximum portability, result set columns within each row should be read in left-to-right order, and each column should be read only once.
rankOfB = hashA.get(resultSet.getString(1));
use busno instead of resultSet.getString(1)
Edited by: whitenight541 on Dec 29, 2008 8:13 AM -
Difference between a regular subquery and a correlated subquery
Can someone explain EXACTLY what is a correlated subquery and could you give me an example? I'm taking an Oracle DBA class and I would appreciate your feedback. Thanks. :)
"Normal" subquery (the subquery is executed only once for the statement):
select name
from emp
where salary > (select avg(emp2.salary) from emp emp2);
Correlated subquery (it is executed for each row of the main query):
select name
from emp
where salary > (select avg(salary) from emp emp2
where emp2.deptno = emp.deptno);
Can someone explain EXACTLY what is a correlated subquery and could you give me an example? I'm taking an Oracle DBA class and I would appreciate your feedback. Thanks. :) -
How SQL engine evaluates a correlated subquery ?
SELECT deptno,ename,sal FROM emp t WHERE sal >
(SELECT AVG(sal) FROM emp WHERE t.deptno = deptno)
ORDER BY deptno;
To get the result table of inner query there should be the table t, which is an instance of the outer result table, that depends on the inner result table. How this query will be processed by SQL engine. I would appriciate, If anybody clarify my doubt.
Thanks.I have created PLAN_TABLE by running utlxplan.sql and grant access to everyone, but I couldn't create synonym to that table, when I tried to create synonym I got the error[b] ORA-01031: insufficient privileges .
I continued to run the explain plan command for my query. I got the following result. I am really confused with this result, cause I am not familiar with the paln table. Could you please tell me how can I get information from this plan table to trace steps taken by the SQL engine to execute the query.
Thanks.
SQL> explain plan for SELECT deptno,ename,sal FROM emp t WHERE sal >
2 (SELECT AVG(sal) FROM emp WHERE t.deptno = deptno)
3 ORDER BY deptno;
Explained.
SQL> SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY());
PLAN_TABLE_OUTPUT
| Id | Operation | Name | Rows | Bytes | Cost |
| 0 | SELECT STATEMENT | | | | |
| 1 | SORT ORDER BY | | | | |
|* 2 | FILTER | | | | |
| 3 | TABLE ACCESS FULL | EMP | | | |
| 4 | SORT AGGREGATE | | | | |
|* 5 | TABLE ACCESS FULL| EMP | | | |
PLAN_TABLE_OUTPUT
Predicate Information (identified by operation id):
2 - filter("SYS_ALIAS_1"."SAL"> (SELECT AVG("EMP"."SAL") FROM
"EMP" "EMP" WHERE "EMP"."DEPTNO"=:B1))
5 - filter("EMP"."DEPTNO"=:B1)
Note: rule based optimization
20 rows selected. -
the following sample is from ORACLE DATABASE 10g SQL
i don't understand how it works, the bellow is the table and the query
SELECT Product_id pid, product_type_id ptid, name, price
FROM products
PID PTID NAME PRICE
1 1 Modern Science 19.95
2 1 Chemistry 30
3 2 Supernova 25.99
4 2 Tank War 13.95
5 2 Z Files 49.99
6 2 2412: The Return 14.95
7 3 Space Force 9 13.49
8 3 From Another Planet 12.99
9 4 Classical Music 10.99
10 4 Pop 3 15.99
11 4 Creative Yell 14.99
PID PTID NAME PRICE
12 My Front Line 13.49
the query
SELECT product_id pid, product_type_id ptid, name, price
FROM products outer
WHERE price >
(SELECT AVG(price)
FROM products inner
WHERE inner.product_type_id = outer.product_type_id)
PID PTID NAME PRICE
2 1 Chemistry 30
5 2 Z Files 49.99
7 3 Space Force 9 13.49
10 4 Pop 3 15.99
11 4 Creative Yell 14.99
what i don't understand is HOW and WHEN the AVG function works and HOW AVG() function knows to calculate the average by grouping the PTID not the average of ALL PRICE column.
tks for helping in advanceThe subquery
(SELECT AVG(price)
FROM products inner
WHERE inner.product_type_id = outer.product_type_id)knows to create an average of all the products with the same product type because of the WHERE clause, which limits the rows returned to those with the product_type_id in the outer.
Conceptually, what happens is
- the outer query gets the first row of the table (PID=1)
- it grabs the price (19.95)
- now, it runs the subquery to determine whether this is above average
- the subquery sees that outer.product_type_id is 1, so the WHERE clause eliminates all but the first two rows (PID 1&2). The average of 19.95 and 30 is 24.975.
- Since the price of the first row is not greater than 24.975, Oracle knows that it does not meet the conditions of the WHERE clause in the outer query.
- Repeat for each row in the outer query
Obviously, since Oracle is doing set-based processing, it may not work exactly this way internally. Conceptually, though, this is how correlated subqueries work.
Justin
Distributed Database Consulting, Inc.
http://www.ddbcinc.com/askDDBC -
Correlated Subquery in ORDER BY
The following is a valid sql. But, what is meant by a correlated scalar subquery in the ORDER BY clause?
SELECT employee_id, last_name
FROM employees e
ORDER BY (SELECT department_name
FROM departments d
WHERE e.department_id=d.department_id);It is exactly the same in the ORDER BY clause as in any other part of a query. As biswabijay says, the correlated query is run once for each row in the result set.
In essence, the fileds selected from the correlated query are added to the result for each row, then evaluated in the appropriate context (e.g. compared in a WHERE clause, used for sorting in an ORDER BY).
A small addition to your original query makes this more apparent.
SQL> SELECT employee_id, last_name, department_name
2 FROM employees e, departments d
3 WHERE e.department_id=d.department_id
4 ORDER BY (SELECT department_name
5 FROM departments d
6 WHERE e.department_id=d.department_id);
EMPLOYEE_ID LAST_NAME DEPARTMENT_NAME
205 Higgins Accounting
206 Gietz Accounting
200 Whalen Administration
100 King Executive
101 Kochhar Executive
102 De Haan Executive
185 Bull Shipping
144 Vargas Shipping
143 Matos Shipping
184 Sarchand ShippingHTH
John -
Correlated subquery alternatives?
Before I start, this is a production system and I am not allowed to alter ANY of the tables involved: so no new columns are allowed, tables can't be changed into being materialized views, and no I can't just re-design the entire application that I've inherited! The ONLY thing I can do is change the SQL code used to perform assorted tasks. The tables involved have all got fresh statistics computed, too, so this isn't a question about improving my DBA techniques. Nor is it a question about tuning the performance of existing code (which already has good execution plans).
I have a large table, called SEARCH. It is a copy of a lot of data from a table called SOURCE (not all of the data, because some is filtered out). SOURCE has about 7 million rows. SEARCH has about 5 million. From time to time, records in SOURCE have their status changed from ACTIVE to INACTIVE. If they are marked INACTIVE, they are not allowed to be in SEARCH. Weekly, we re-synch the SEARCH data with the SOURCE -so, it's during that weekend refresh operation that this sort of query is issued:
delete from SEARCH where IDENTIFIER in (select IDENTIFIER from SOURCE where STATUSCODE != 1);It's a delete using a standard correlated sub-query. It takes slightly over five minutes to run, which is OK, but I would like to know if there's any alternative SQL or SQL constructs/features/enhancements which could be used to perform the same sort of thing more quickly. As I say, I'm not asking how to tune this sort of thing: I'm asking rather if there are alternatives to it. If there isn't, that's OK.
I should perhaps add that the STATUSCODE column is not found in the SEARCH table (because if the record's in SEARCH, it would be because the status was =1 in SOURCE originally)I tried very hard to prevent this sort of post, but clearly I have not succeeded.
The question actually asked whether there were SQL constructs which could act as an alternative to a correlated sub-query. I see two people have been able to supply such alternatives.
Those people did not need to double-think what 'active' and 'inactive' meant, or whether the value stored in the statuscode column was 'active' or '1' (I expect they were smart enough to work out that a "status" of active can be encoded in a column called "statuscode" with a value of '1')
Those people did not read the words "I can't alter any of the tables" and then decide to ignore them as you have (creating an index on a table counts as altering the table in my book and in this context)
Those people did not read the words 'fresh statistics have been computed' and decide to suggest calculating even fresher statistics that include histograms.
Those people did not need to start guessing what my data distribution for inactive records is.
Those people did not read the words "[This is not] a question about tuning the performance of existing code (which already has good execution plans)" and ignore them, deciding in their arrogance that maybe those execution plans needed to be discussed after all.
Why can't you and others like you just stick to answering the question as asked for once? Two other people in this exchange have managed to do just that, yet so many of these 'thousands of posts to my name' frequenters of these forums seem completely incapable of doing so. It is very strange, very frustrating and I wish you wouldn't do it. -
Flattening, correlated subquery
Hi,
The following fields are key values on a table, with example data :
EMPNO DATE ACTION
1234 6/6/05 HIR
1234 6/6/05 XFR
1234 6/10/05 DTA
1234 6/22/05 XFR
1234 7/30/05 TER
3456 6/6/05 HIR
etc.
I need to create a view to show the previous 5 rows of history per employee but flattened to be one line per Employee Number (EMPNO).
So the view would be something like :
EMPNO ACTION1 DATE1 ACTION2 DATE2 ACTION3 DATE3 (etc.)
1234 HIR 6/6/05 XFR 6/6/05 DTA 6/10/05
I have thought of aliasing the table and then using correlated subqueries, but this got complicated joining to >2 tables. Since joining to table 2 required that DATE1 <> DATE2 or ACTION1 <> ACTION2. But then alias 3 becomes more convoluted and then 4 and 5 OTT.
I also looked at some rownum trickery to get the <=5 rows, but I could not get this working.
What is the best solution for this problem ? Note that it does have to be a pure view, not PL/SQL etc.
Thanks,
T0rrentI think you are after this. You must know the number of actions per output row. In this case five:
drop table t;
create table t( empno number, x_date date, action varchar2(3));
insert into t values (1234, to_date('6/6/05 01:00','mm/dd/yy hh:mi'),'HIR'); --need to have unique date values per empno
insert into t values (1234, to_date('6/6/05 02:00','mm/dd/yy hh:mi'),'XFR'); --need to have unique date values per empno
insert into t values (1234, to_date('6/10/05','mm/dd/yy'),'DTA');
insert into t values (1234, to_date('6/22/05','mm/dd/yy'),'XFR');
insert into t values (1234, to_date('7/30/05','mm/dd/yy'),'TER');
insert into t values (3456, to_date('6/6/05','mm/dd/yy'),'HIR');
commit;
create or replace view tv as
select empno, x_date, action, dense_rank() over( partition by empno order by x_date ) e_rank
from t
order by empno;
SELECT empno,
max( decode( e_rank, 1, x_date||' '||action)) e_act1,
max( decode( e_rank, 2, x_date||' '||action)) e_act2,
max( decode( e_rank, 3, x_date||' '||action)) e_act3,
max( decode( e_rank, 4, x_date||' '||action)) e_act4,
max( decode( e_rank, 5, x_date||' '||action)) e_act5
FROM tv
group by empno;
EMPNO E_ACT1 E_ACT2 E_ACT3 E_ACT4 E_ACT5
1234 06-JUN-05 HIR 06-JUN-05 XFR 10-JUN-05 DTA 22-JUN-05 XFR 30-JUL-05 TER
3456 06-JUN-05 HIR
Maybe you are looking for
-
Hello there, I'm doing a search and results page for my DB, I did the recordset on the results page and the form on the search page as explained in the DW's Docs but when I try a search I get this error: Parse error: syntax error, unexpected ')', exp
-
TV SERIES outside the United States
How's it possible to purchase tv episodes from american tv in Europe with my account in iTunes? Totally impossible? What if I buy itunes checks online and I used them for buying those episodes? would it work?? I'm fan of TV series already being broad
-
Hi All, Is syndication server required for syndicate step in workflow? I have doubt that syndicate step is for either manually syndicating or automatically syndicating. Please clarify. Thanks Narendra
-
4.6c to Unicode upgrade
Hi all, I am moving a report (which has been successfully running in 4.6c) to a new system with UNICODE check. In my current system(4.6c) I want to do a UNICODE syntax check before moving to the new system. If it is possible please let me know with a
-
We are running Hyperion IR 11. I've got an issue I'm trying to resolve, and haven't found a way to do it yet. So I have imported a BQY as a job in Hyperion Workspace, and it processes its large amount of queries just fine weekly. We previously had a