Skip to Main Content

Breadcrumb

Question and Answer

Chris Saxon

Thanks for the question, Steffen.

Asked: November 30, 2016 - 7:00 am UTC

Last updated: December 01, 2016 - 9:49 am UTC

Version: Oracle Database 12c Enterprise Edition Release 12.1.0.2.0

Viewed 1000+ times

You Asked

Hi all,

per random I came to this problem.
My PL/SQL-Procedure was parsed without any ERROR, whereby the column "tb_id" itself did not exist in "suh_tb_test_1".
(If I use an alias in the subquery then the ERROR is thrown!)

Here the (strong simplified) problem, that also exists in "clean" SQL.
https://livesql.oracle.com/apex/livesql/s/d70igkq134fnkq60puf0h1g68

If you check this link, than you will find the problem description in statement 7 ,8 ,12 ,13 ("tb_id does not exist in suh_tb_test_1!!").

With best regards
St. Uhlig

with LiveSQL Test Case:

and Chris said...

No, this isn't a bug!

In your query:

SELECT  a.tb_id
FROM  suh_tb_test a
WHERE a.tb_id NOT IN  (
  SELECT tb_id -- tb_id does not exist in suh_tb_test_1!!
  FROM  suh_tb_test_1
)


TB_ID resolves to the column in suh_tb_test! Just because you've selected it in the subquery, doesn't mean the column "belongs" to suh_tb_test_1.

If you use table aliases this becomes clear:

SQL> create table suh_tb_test (
  2    tb_id    number
  3  );

Table created.

SQL>
SQL> create table suh_tb_test_1 (
  2    tb_1_id    number
  3  );

Table created.

SQL>
SQL> select  a.tb_id
  2  from   suh_tb_test a
  3  where  a.tb_id not in   (
  4    select s1.tb_id
  5    from   suh_tb_test_1 s1
  6  );
  select s1.tb_id
         *
ERROR at line 4:
ORA-00904: "S1"."TB_ID": invalid identifier


SQL>
SQL> select  a.tb_id
  2  from   suh_tb_test a
  3  where  a.tb_id not in   (
  4    select a.tb_id
  5    from   suh_tb_test_1 s1
  6  );

no rows selected


Fully qualify your columns (with table aliases) and you'll avoid possible mix-ups like this.

http://stevenfeuersteinonplsql.blogspot.co.uk/2016/10/weird-sql-behavior-no-and-importance-of.html

Rating

  (3 ratings)

Is this answer out of date? If it is, please let us know via a Comment

Comments

Steffen Uhlig, November 30, 2016 - 12:01 pm UTC

Attention! - The problem remains also if I use the same alias name!!! - that means - I have to use in every case a different alias!!
Chris Saxon
November 30, 2016 - 2:07 pm UTC

What do you mean "same alias name"?

Resolution by automation

Duke Ganote, November 30, 2016 - 3:06 pm UTC

I stumbled across this behavior several months ago when I was doing some data profiling. Suddenly I realized I needed to double-check my results! The behavior is easily demonstrated:

SQL> select count(*) from user_tables where table_name in ( select table_name from user_views );

    COUNT(*)
------------
          58

SQL> select count(*) from user_tables --where table_name in ( select table_name from user_views );

    COUNT(*)
------------
          58


Clearly there's no TABLE_NAME column in USER_VIEWS, but the first query runs!

I was looking for anomalies between a reference table and the transaction table, and I never found any. I kept plugging away -- until at one point I realized I was comparing a "reference table" that didn't even have the column in question:

SQL> select count(*) from user_tables where table_name not in ( select table_name from user_views );

    COUNT(*)
------------
           0


USER_VIEWS contains the names of every table?? No... not quite!
Chris Saxon
November 30, 2016 - 4:02 pm UTC

Indeed. Another example of the importance of qualifying your columns!

10053 Trace

Rajeshwaran, Jeyabal, December 01, 2016 - 6:56 am UTC

Looking into the 10053 Trace could explain the things even better.

demo@ORA12C> @10053

Session altered.

demo@ORA12C> explain plan for
  2  SELECT     a.tb_id
  3  FROM       suh_tb_test a
  4  WHERE      a.tb_id NOT IN  (SELECT         tb_id   FROM    suh_tb_test_1);

Explained.

demo@ORA12C> exit
Disconnected from Oracle Database 12c Enterprise Edition Release 12.1.0.2.0 - 64bit Production
With the Partitioning, OLAP, Advanced Analytics and Real Application Testing options


Final query after transformations:******* UNPARSED QUERY IS *******

SELECT "A"."TB_ID" "TB_ID"
FROM "DEMO"."SUH_TB_TEST" "A"
WHERE NOT EXISTS
  (SELECT 0
  FROM "DEMO"."SUH_TB_TEST_1" "SUH_TB_TEST_1"
  WHERE LNNVL("A"."TB_ID"<>"A"."TB_ID")
  )

Chris Saxon
December 01, 2016 - 9:49 am UTC

Reaching for a 10053 trace to "solve" this seems a bit extreme to me...

More to Explore

PL/SQL demos

Check out more PL/SQL tutorials on our LiveSQL tool.

PL/SQL docs

PL/SQL reference manual from the Oracle documentation library