突然遇到一个很奇怪的问题,详细如下:
select subs_id from cust;cust表中没有subs_id字段所以会报出“subs_id invalid identifier”的错误。但是select * from subs where subs_id in (select subs_id from cust@link_cc);
却能正确执行,且得到了subs表中的全部记录。 注: subs表主键就是subs_id。问题就是很奇怪,单独执行 select subs_id from cust;会报错,这我理解,cust表中根本就没有subs_id属性字段嘛。
但是怎么放到一个in从句中就行了呢?还不报错?在网上找了半天也没有答案,难道是SQL的bug,这是在ORACLE10g中试验的。望高手解答。

解决方案 »

  1.   

    select subs_id from cust@link_ccselect subs_id from cust;后面的表不一样了
      

  2.   

    我是楼主,不是楼上的原因啊,两个表是一样的,是我大意了
    select * from subs where subs_id in (select subs_id from cust@link_cc);
    应该是
    select * from subs where subs_id in (select subs_id from cust;
      

  3.   

    select subs_id from cust@link_cc不是同一库。一个是本地的cust表,一个是dblink link_cc库的cust表。远程cust表有subs_id列
      

  4.   

    不是BUG
    第二个语句相当于
    select * from subs where subs_id in (select subs.subs_id from cust)
    语法解析的时候,没有在cust表中找到subs_id,就取了subs表中的对应字段
    你可以试试将子查询里的cust表改成dual,照样能够执行,这个查询已经不能对记录进行过滤
      

  5.   

    多谢楼上的回复,不过我有必要在重复一遍:
    大家不要再从@link_cc上多思考了,与链接没关系的,都是同一个数据库实例,开始我写的cust@link_cc 
    是手误。压根就没有@link_cc 的
      

  6.   

    to 5楼:
    为什么会是这种逻辑呢?如果第二个语句相当于:
    select * from subs where subs_id in (select subs.subs_id from cust);
    在cust中找不到subs_id,那应该相当于是null啊,整个句子就应该相当于:
    select * from subs where subs_id in null;
    这样才合理啊
      

  7.   

    OPER@XE> select * from test;       AAA
    ----------
             1OPER@XE> select * from test2;       BBB
    ----------
             1
             2OPER@XE> set autot on explain
    OPER@XE> select * from test2 where bbb in(select bbb from test);       BBB
    ----------
             1
             2
    执行计划
    ----------------------------------------------------------
    Plan hash value: 3707675100-----------------------------------------------------------------------------
    | Id  | Operation           | Name  | Rows  | Bytes | Cost (%CPU)| Time     |
    -----------------------------------------------------------------------------
    |   0 | SELECT STATEMENT    |       |     2 |    26 |     4   (0)| 00:00:01 |
    |*  1 |  FILTER             |       |       |       |            |          |
    |   2 |   TABLE ACCESS FULL | TEST2 |     2 |    26 |     2   (0)| 00:00:01 |
    |*  3 |   FILTER            |       |       |       |            |          |
    |   4 |    TABLE ACCESS FULL| TEST  |     1 |       |     2   (0)| 00:00:01 |
    -----------------------------------------------------------------------------Predicate Information (identified by operation id):
    ---------------------------------------------------   1 - filter( EXISTS (SELECT /*+ */ 0 FROM "TEST" "TEST" WHERE
                  :B1=:B2))
       3 - filter(:B1=:B2)in部分转换为:
    SELECT 0 FROM "TEST" "TEST" 
      

  8.   

    汗...第二个subs_id是在subs 的有效范围内, 当然可以找到.
      

  9.   

    In里面的查询结果将产生一个记录条数和cust表的总记录数相同,字段值全是当前subs.subs_id这样一个数据集
    如果你希望按你想的那样查询,在字段名前面显式地加上表名:
    select * from subs where subs_id in (select cust.subs_id from cust)
    这个应该就会按你预想的那样报错了..
      

  10.   

    里面的子查询可以调用外面的字段的,这样就会不报错了
    如果:你把子查询的cust别名,再把subs_id改为别名.cust之后就肯定报错了