Could the Runtime Exception (column list_id does not exist) come from left join? - sql

In my Android Studio project I have implemented a database (managed by Room). In my Dao file, I have the following query which causes an error:
SELECT tab1.list_id, ... FROM
(SELECT list_id, ... FROM list_table) AS tab1
LEFT JOIN
(SELECT list_id, ... FROM list_table NATURAL JOIN product_table NATURAL JOIN list_product_table GROUP BY list_id) AS tab2
ON tab1.list_id = tab2.list_id
ORDER BY list_position ASC, tab1.list_id ASC;
The error says java.lang.IllegalArgumentException: column '`list_id`' does not exist. The error points to the file, which was automatically created by Room.
...
return __db.getInvalidationTracker().createLiveData(new String[]{"list_table","product_table","list_product_table"}, false, new Callable<List<ShoppingListDisplayValues>>() {
#Override
public List<ShoppingListDisplayValues> call() throws Exception {
final Cursor _cursor = DBUtil.query(__db, _statement, false, null);
try {
final int _cursorIndexOfPosition = CursorUtil.getColumnIndexOrThrow(_cursor, "list_position");
final int _cursorIndexOfId = CursorUtil.getColumnIndexOrThrow(_cursor, "list_id");
...
To be more specific, the error points to the line:
final int _cursorIndexOfId = CursorUtil.getColumnIndexOrThrow(_cursor, "list_id");
Now my question is, could this error result from the left join? The really weird thing is, that the code works on some devices and on other not. Would be really glad, if someone has an idea.

So, after debugging a couple of hours I found the error and a solution.
Error origin
The error lies in the Room persistence library. When using this library on devices with API lower than 27 (at least this is what I guess, since I tested 3 devices with different APIs), then an exception gets thrown IF you use a table prefix in your SELECT statement. By "table prefix" I mean for example the tab1. in tab1.list_id.
The solution:
Just use an alias for the column which has a table prefix.
Instead of
SELECT tab1.list_id, ... FROM
write
SELECT tab1.list_id AS list_id, ... FROM

Related

SQL code using 'as' resulting in not being able to run

SQL microsoft server
I’m quite close with this piece of code… having said that I haven’t got it to run successfully yet… there seems to be issues with me naming ‘tableabc’ (At the end of the first ‘from’).
Ie the line: WHERE R.PE.d_R_month = (SELECT MAX(d_R_month) FROM R.PE)) AS tableabc
The error I am getting is: “The column 'id' was specified multiple times for 'tableabc'.”
Just for a bit of context, the code does the following:
‘tableabc’ left joins to A.PS table, based on different conditions (As listed).
(I have named the following output as ‘tableabc’. A new column in the R.PAS table is added (and is a summation of the ‘date and month’ creating a column called ‘newdate.’) It then right joins to another table (R.PE) and there are additional conditions applied (ie the maximum dates are only shown)
Select
A.PS.id,
A.PS.name,
A.PS.current_phase,
A.PS.asset_id,
A.PS.production_category,
tableabc.*
FROM
(select R.PAS.*, R.PE.*, DATEADD(month, [R].[PAS].[months_accelerated], [R].[PE].[d_date]) as 'newdate'
from R.PAS
Right join R.PE
On [R].[PAS].[id] = [R].[PE].[id]
WHERE R.PE.d_R_month = (SELECT MAX(d_R_month) FROM R.PE)) AS tableabc
LEFT JOIN A.PS
ON tableabc.id = A.PS.id
Where A.PS.prod = 'Include' OR A.PS.R_category <> 'Can' or A.PS.R_category <> 'Hold';

Core Data SUBQUERY with key-path collection causes SQL error

I'm experiencing a SQL error from a Core Data-generated query. Here's the data model:
I want to get all of the drivers for whose busses have active passengers. This is simply described by the following fetch request and predicate, which works:
NSFetchRequest(entityName: "Driver")
NSPredicate(format: "ANY bus.passengers.active == YES")
However, let's say I want to do a more complex query on the passenger, like they are both active and a balance above 100. To do such a query, I'd have to use a SUBQUERY, like so:
NSPredicate(format: "SUBQUERY(bus.passengers, $passenger, $passenger.active == YES
AND $passenger.balance > 100).#count > 0")
I would expect SUBQUERY to accept a keypathed collection as its first argument. It generates the following SQL query:
SELECT 0,
t0.z_pk,
t0.z_opt,
t0.zbus
FROM zdriver t0
WHERE (SELECT Count(t2.z_3passengers)
FROM zbus t1
JOIN z_1passengers t2
ON t1.z_pk = t2.z_1busses
WHERE ( t0.zbus = t1.z_pk
AND (( t2.zactive = ?
AND t2.zbalance > ? )) )) > ?
And the error: 'no such column: t2.ZACTIVE'. It looks like it's missing a JOIN on the ZPASSENGER table.
Is this a Core Data bug or is there a different way to write this predicate?
Update: Here's a sample project that reproduces this issue.
Try fetching the Bus entity, avoiding the key path in the first argument in the SUBQUERY.
As was pointed out, this can be viewed as a limitation or a bug.
Update:
Further research suggests that your subquery predicate should actually work. I would recommend to check your NSManagedObject subclasses and make sure passengers returns a collection and active is properly listed as an attribute.

ORA-00918: column ambigously defined, using DB Link

When I execute the query below I get the following error message :
ORA-00918: column ambigously defined
ORA-02063: preceding line from ABC
Query:
SELECT
dos.*,
cmd.*,
cmd_r.*,
adr_inc.*,
adr_veh.*,
loc.*,
fou_d.*,
fou_r.*, --Works if I comment this line
mot.*
FROM
DOSSIERS#ABC dos
LEFT JOIN CMDS#ABC cmd ON cmd.DOS_CODE_ID = dos.dos_code_id
LEFT JOIN CMDS_RECCSTR#ABC cmd_r ON cmd_r.DOS_CODE_ID = dos.DOS_CODE_ID AND cmd_r.CMD_CODE_ID = cmd.CMD_CODE_ID AND cmd_r.CMD_DT_CREAT = cmd.CMD_DT_CREAT
LEFT JOIN HISTO_ADR#ABC adr_inc ON adr_inc.DOS_CODE_ID = dos.DOS_CODE_ID
LEFT JOIN HISTO_ADR#ABC adr_veh ON adr_veh.DOS_CODE_ID = dos.DOS_CODE_ID
LEFT JOIN LOC#ABC loc ON dos.DOS_CODE_ID = loc.DOS_CODE_ID
LEFT JOIN FOURNISS#ABC fou_d ON fou_d.PAY_CODE_ID = loc.PAY_CODE_ID_D AND fou_d.FOU_CODE_ID = loc.FOU_CODE_ID_D
LEFT JOIN FOURNISS#ABC fou_r ON fou_r.PAY_CODE_ID = loc.PAY_CODE_ID_R AND fou_r.FOU_CODE_ID = loc.FOU_CODE_ID_R
LEFT JOIN REF_MOT#ABC mot ON mot.RMR_CODE_ID = cmd_r.RMR_CODE_ID
WHERE
dos.REF_EXT = 'XXXXXXX'
If I comment fou_r.* in SELECT it works.
The following queries don't work neither:
SELECT *
FROM ... ;
SELECT (SELECT count(xxx) FROM ...)
FROM ...;
I looked at similar issues on SO but they were all using complex queries or was using many SELECT inside WHERE. Mine is simple that is why I don't understand what could be wrong.
Current Database: Oracle Database 11g Enterprise Edition Release 11.2.0.2.0 - 64bit Production
Target Database (refers to db link ABC target): Oracle Database 10g Enterprise Edition Release 10.2.0.3.0 - 64bi
Client: Toad for Oracle 9.7.2.5
You seem to be hitting bug 13589271. I can't share details from MOS, but there isn't much to share anyway. It's related to the remote table having a column with a 30-character name though, as you have in your remote FOURNIUSS table.
Unfortunately simply aliasing the column in your query, like this:
fou_d.COLUMN_WITH_30_CHARACTERS_NAME alias_a,
fou_r.COLUMN_WITH_30_CHARACTERS_NAME alias_b,
... doesn't help and still gets the same error, as the alias is applied by the local database and the problem seems to be during the remote access. What does seem to work is using an in-line view to apply a column alias before the join:
...
LEFT JOIN LOC#ABC loc ON dos.DOS_CODE_ID = loc.DOS_CODE_ID
LEFT JOIN (
SELECT PAY_CODE_ID, FOU_CODE_ID, COLUMN_WITH_30_CHARACTERS_NAME alias_a FROM FOURNISS#ABC
) fou_d ON fou_d.PAY_CODE_ID = loc.PAY_CODE_ID_D AND fou_d.FOU_CODE_ID = loc.FOU_CODE_ID_D
LEFT JOIN (
SELECT PAY_CODE_ID, FOU_CODE_ID, COLUMN_WITH_30_CHARACTERS_NAME alias_b FROM FOURNISS#ABC
) fou_r ON fou_r.PAY_CODE_ID = loc.PAY_CODE_ID_R AND fou_r.FOU_CODE_ID = loc.FOU_CODE_ID_R
LEFT JOIN REF_MOT#ABC mot ON mot.RMR_CODE_ID = cmd_r.RMR_CODE_ID
...
This even works if you give the column the same alias in both inline views. The downside is that you have to explicitly list all of the columns from the table (or at least those you're interested in) in order to be able to apply the alias to the problematic one, but having done so you can still use fou_d.* and fou_r.* in the outer select list.
I don't have an 11.2.0.2 database but I've run this successfully in an 11.2.0.3 database which still showed the ORA-00918 error from your original code. It's possible something else in 11.2.0.2 will stop this workaround being effective, of course. I don't see the original problem in 11.2.0.4 at all, so upgrading to that terminal patch release might be a better long-term solution.
Using * is generally considered a bad practice anyway though, not least because you're going to get a lot of duplicated columns from the joins (lots of dos_code_id in each row, for example); but you're also likely to be getting other data you don't really want, and anything that consumes this result set will have to assume the column order is always the same in those tables - any variation, or later addition or removal of a column, will cause problems.

Syntax Error - Missing Operator - Cannot determine what is missing

What is wrong with the SQL statement? I get a message that there is a syntax error (missing operator). From the ASSIGNMENT TABLE I am wanting to select all rows where ASSN_TRANS_STATE_NUM = '1'. For each of these rows I then want to get the project name from the PROJECTS table. I also want to get each of the Task names from the TASKS table. I did get this to work earlier (not sure what change I made that broke it) but even when it did work it was not correct. It was reporting every task for each of the projects, instead of just giving me the tasks specific to a project.
SELECT
TRANS.PROJ_UID,
PROJ.PROJ_NAME,
TRANS.TASK_UID,
TASKS.TASK_NAME,
TRANS.ASSN_TRANS_STATE_ENUM,
TRANS.ASSN_TRANS_APPROVER_RES_UID
FROM dbo_MSP_ASSIGNMENT_TRANSACTIONS TRANS
INNER JOIN dbo_MSP_PROJECTS PROJ ON PROJ.PROJ_UID = TRANS.PROJ_UID
INNER JOIN dbo_MSP_TASKS TASKS ON TASKS.TASK_UID = TRANS.TASK_UID
WHERE TRANS.ASSN_TRANS_STATE_ENUM = 1;
It will be dbo. rather than dbo_. I guess it should help
SELECT
TRANS.PROJ_UID,
PROJ.PROJ_NAME,
TRANS.TASK_UID,
TASKS.TASK_NAME,
TRANS.ASSN_TRANS_STATE_ENUM,
TRANS.ASSN_TRANS_APPROVER_RES_UID
FROM dbo.MSP_ASSIGNMENT_TRANSACTIONS TRANS
INNER JOIN dbo.MSP_PROJECTS PROJ ON PROJ.PROJ_UID = TRANS.PROJ_UID
INNER JOIN dbo.MSP_TASKS TASKS ON TASKS.TASK_UID = TRANS.TASK_UID
WHERE TRANS.ASSN_TRANS_STATE_ENUM = 1;

NHibernate: Double nested subqueries and "Could not find a matching criteria info provider..."

I am having trouble working out how to get the following sql into an NHibernate ICriteria:
select * from Contract contract_outer
where exists (
select 1 from RequiredDocRules
where not exists (
select 1 from Contract contract_inner
inner join ContractDocs contractDocs on cDocs.ContractId = c_inner.Id
inner join Doc doc doc.Id = contractDocs.DocId
where contract_inner.Id = contract_outer.Id
and doc.Type = RequiredDocRules.DocType)
)
and RequiredDocRules.ContractType = contract_outer.Type
)
Basically, the query is saying "Show me contracts that are missing required documents, based on the rules for this type of contract".
The CreateCriteria looks like this:
var subqueryB = DetachedCriteria.For<Contract>("contract_inner")
.CreateAlias("contract_inner.Docs", "doc")
.Add(Restrictions.EqProperty("doc.Type", "rule.DocType"))
.Add(Restrictions.EqProperty("contract_inner.Id", "contract_outer.Id")
.SetProjection(Projections.Id());
var subqueryA = DetachedCriteria.For<RequiredDocRule>("rule")
.Add(Restriction.EqProperty("rule.ContractType", "contract_outer.Type"))
.Add(Subqueries.NotExists(subqueryB))
.SetProjection(Projections.Id());
return Session.CreateCriteria<Contract>("contract_outer")
.Add(Subqueries.Exists(subqueryA))
.List<Contract>();
This above code throws the following obscure exception:
Could not find a matching criteria
info provider to: contract_inner.Id =
contract_outer.Id and doc.Type =
rule.DocType
I've narrowed the issue down to the "contract_inner.Id = contract_outer.Id" restriction. Maybe it is having trouble traversing up through two layers of subqueries?
I am using NHibernate 2.1 btw.
I seem to be the only person getting this exception - if you google for the exception message another one of my Stackoverflow posts comes up number one. This question is similar, but different. So frustrating!