I'm using Oracle 10g (XE 10.2.0.1.0), and find a behavior that I don't understand:
select *
from employees manager
join employees worker on MANAGER.EMPLOYEE_ID = WORKER.MANAGER_ID
join departments on DEPARTMENTS.manager_id = 108
where
department_id = 100
;
The problem is I think Oracle should have complain about the ambiguity of department_id in the where clause, since it's a column in both the table employees and departments. The fact is in Oracle 10g, it doesn't, and the result shows that it interprets the department_id as the one in departments. However, if I comment out the second join statement (4th line above), Oracle does complain “ORA-00918: column ambiguously defined” as expected.
So, can somebody help to explain how the ambiguity is defined in Oracle 10g? Or perhaps this is a bug in 10g?
BTW: The tables are defined in the default HR schema bundled in the Oracle 10g.
Update: Just found a related post:
Why does Oracle SQL mysteriously resolve ambiguity in one joins and does not in others
I believe it is a bug in Oracle 10g that Oracle chose not to fix. When we were upgrading our applications from 10g to 11gR2, we found a couple of queries that were written "loosely" in respect of ambiguous column names but worked in Oracle 10g. They all stopped working in 11gR2. We contacted Oracle but they pretty much said that the tolerant behavior toward ambiguous column names is a correct behavior for Oracle 10g and the stringent behavior is the correct behavior for 11g.
I think it is, because departments have no alias. Therefore everything without being qualified by an <alias>. is first treated to be from departments.
So I also think when you give departments an alias you should get the ORA-00918 again. Cannot test here though...
Related
Something very strange has happened since we migrated our schemas/database from 12c to 19c
When I insert records to a table and I check the row count
namely under my oracle user - say SMITH_J - I see 4 records. Good I am happy.
When my Java application looks at the same table which I will call QUEUE_TAB - using the application oracle user - say APP_TOMCAT - it just sees ZERO records. How can that be ?
I check the GRANTS for APP_TOMCAT - it has everything that should be there for that table - it's got SELECT,INSERT,UPDATE,DELETE - which it had before.
What is really perplexing why are the record counts different - despite all the privileges being the same ? Is there something here that I have overlooked OR cannot see at the moment ? Is it something to do with privileges going from 12c to 19c ?
I owe the correct answer to Alex Poole in the comments above.
I was using a procedure to populate the table in question. And, foolishly assumed that the procedure would commit it. Of, course, it would have if it DID have a COMMIT within the code at the end of the procedure. So, after EXECUTING the procedure - I issued a COMMIT and it worked.
It's best practice NOT to have a COMMIT statement within your procedure even if it is a single procedure. See the comments of #MTO and #Alex Poole below
Oracle Forms 10g - 'NULLS' is not accepted.
In program unit(PL/SQL Code) I use NULLS FIRST and its throwing error.
Encountered the symbol NULLS
select line_id
from oe_order_lines_all
where rownum <5
order by line_id NULLS FIRST;
kindly help
I am not familiar with forms, but a simple workaround (if it works) is to modify the order by clause. For example, assuming the line id's are positive, or at least non-negative, you could
order by nvl(line_id, -1)
The flavour of PL/SQL and SQL used in Forms is different and somewhat older than the one available in the database. Being able to run code on the database does not mean it will run without changes in Forms. Analytic functions is an example of a newer SQL feature which is missing in Forms. But you can always put your code into a PL/SQL package in the database and call it from your forms code.
I have multiple Oracle queries that I want to transform to Sybase language. Since Am new to Sybase i was wondering if we can insert subquery in "create clause" or in "delete clause" in sybase ?
create table LIQ_PURGE_AK as select M_REFERENCE from LPOS_AK_DBF where M_PRIC_TYPE in (2, 3)
select distinct M_PROD_OREF from LPOS_DTL_DBF where M_REFERENCE in (select M_OBJ_DETAIL from LPOS_LQE_DBF where M_AK_CLASS = 'MEqGp44051' and M_AK_REF in (select M_REFERENCE from LIQ_PURGE_AK3))
delete from LPOS_DTL_DBF where M_REFERENCE in (select M_OBJ_DETAIL from LPOS_LQE_DBF where M_AK_CLASS = 'MEqGp44051' and M_AK_REF in (select M_REFERENCE from LIQ_PURGE_AK3))
this case:
create table LIQ_PURGE_AK as select M_REFERENCE from LPOS_AK_DBF where M_PRIC_TYPE in (2, 3)
you could change to:
select M_REFERENCE into LIQ_PURGE_AK from LPOS_AK_DBF where M_PRIC_TYPE in (2, 3)
all other case you could leave "AS IS". You could be free with subquery in the delete clause (but could be exceptions with a group by)
Remark #1: I'm assuming you're talking about Sybase ASE here (the SQL dialect for Sybase IQ and Sybase SQL Anywhere is different). To let folks help you, always specify the product you're using and the actual version. "Sybase" is not a database , but a family of databases with many differences between them.
Raemark #2: there's only one good way to solve such issues, and that is to try and run it. You can (and should) download one of the free versions of ASE to try these things out. See www.sypron.nl/ase_free
Remark #3: The CREATE TABLE...SELECT syntax is not valid in ASE. You can however do SELECT-INTO, which creates the table (unlike the SELECT-INTO in other SQL dialects which assigns retrieved values to variables). Look up the SELECT-INTO syntax in the ASE documentation at http://infocenter.sybase.com/help/index.jsp?topic=/com.sybase.infocenter.help.ase.15.7.sp100/doc/html/title.html (note that the name Sybase has been formally dropped, but that doesn't matter for all intents and purposes)
yesterday I've been trying to make this code work inspite the fact it's just working fine with nhibernate and SQL server but when it come to oracle it generate wrong sql
UnitOfWork.Current.CreateCriteria<Bill>().Add(Restrictions.IsEmpty("ReqId"))
.SetMaxResults(BatchSize).SetLockMode(LockMode.Upgrade).List<Bill>();
the generated SQL will something like
Select * from
(Select bill_0.id,bill_0.BillNo ...... from Bill bill_0 where bill_0.reqId is Not null )
where ROWNUM < 10 for UPDATE of bill_0.ID
so i wont run because the allies bill_o is defined inside the inner sql statement so who got the solution ?
the correct sql would be something like this which i tried and worked on oracle db
Select bill_0.id,bill_0.BillNo ...... from Bill bill_0
where bill_0.reqId is Not null and ROWNUM < 10 for UPDATE of bill_0.ID
Since, as you say, NHibernate is generating invalid Oracle SQL, I suggest you file a bug with the NHibernate people. The SQL would work if the in-line view had been assigned an alias of "bill_0", or if the FOR UPDATE clause didn't use a table alias ("for UPDATE of ID"). Whether you can modify your NHibernate calls to make either of these happen I'm afraid I have no idea.
Oracle 9i has nested tables, however it doesn't have the all_nested_table_cols sysview (like 10g and 11g) which lets me see what the columns are for these nested tables. How can I find this information on a 9i database?
I don't have a 9i instance to test with, but maybe this can get you started:
SELECT nt.owner, nt.table_name, nt.parent_table_name, nt.parent_table_column, ct.owner, ct.type_name, ta.*
FROM all_nested_tables nt, all_coll_types ct, all_type_attrs ta
WHERE ct.type_name = nt.table_type_name
AND ta.type_name = ct.elem_type_name
The attr_name column should be something like the column_name column in all_nested_table_cols. I know it's not the real thing... but it's a start.
Making this CW in case anyone wants to improve it.