发表于: 2008.06.06 11:51
分类: ORACLE
出处: http://yangtingkun.itpub.net/post/468/463853
---------------------------------------------------------------
昨天测试BUG的时候使用标准SQL的连接写法偶然发现的问题,这里简单记录一下。
看一个简单的例子:
SQL> CREATE TABLE T (ID NUMBER, NAME VARCHAR2(30));
表已创建。
SQL> CREATE TABLE T1 (ID NUMBER, NAME VARCHAR2(30));
表已创建。
SQL> INSERT INTO T VALUES (1, 'T');
已创建 1 行。
SQL> INSERT INTO T1 VALUES (1, 'T1');
已创建 1 行。
SQL> COMMIT;
提交完成。
SQL> SELECT ID, NAME FROM T, T1
2 WHERE T.ID = T1.ID
3 ;
SELECT ID, NAME FROM T, T1
*第 1 行出现错误:
ORA-00918: 未明确定义列
SQL> SELECT ID, NAME FROM T INNER JOIN T1
2 ON T.ID = T1.ID
3 ;
SELECT ID, NAME FROM T INNER JOIN T1
*第 1 行出现错误:
ORA-00918: 未明确定义列
显然这种写法无论是对Oracle的默认写法,还是对标准SQL写法,都是行不通的,因为Oracle无法确定查询的ID和NAME是属于哪张表的。
那么下面增加一张表:
SQL> CREATE TABLE T2 (ID NUMBER, NAME VARCHAR2(30));
表已创建。
SQL> INSERT INTO T2 VALUES (1, 'T2');
已创建 1 行。
SQL> SELECT ID, NAME FROM T, T1, T2
2 WHERE T.ID = T1.ID
3 AND T.ID = T2.ID;
SELECT ID, NAME FROM T, T1, T2
*第 1 行出现错误:
ORA-00918: 未明确定义列
SQL> SELECT ID, NAME
2 FROM T INNER JOIN T1
3 ON T.ID = T1.ID
4 INNER JOIN T2
5 ON T.ID = T2.ID;
ID NAME
---------- ------------------------------
1 T2
神奇的现象出现了,对于Oracle的默认写法,Oracle仍然报错未明确定义列,但是对于标准SQL写法,居然可以成功执行,而且根据查询结果看,返回的记录是T2表的,那么是否可以这样进行推测,对于标准写法而言,如果查询的时候不指定列的所在表信息,那么Oracle选择最后一个连接表的列。
再做一个简单的例子验证一下这个推测:
SQL> CREATE TABLE T3 (ID VARCHAR2(1), NAME VARCHAR2(30));
表已创建。
SQL> INSERT INTO T3 VALUES ('1', 'T3');
已创建 1 行。
SQL> SELECT ID, NAME
2 FROM T INNER JOIN T1
3 ON T.ID = T1.ID
4 INNER JOIN T2
5 ON T.ID = T2.ID
6 INNER JOIN T3
7 ON T.ID = T3.ID;
I NAME
- ------------------------------
1 T3
果然如此,只是不知道这个特性是标准函数写法中规定的,还是Oracle自己的特性。











