Oracle数据库数据恢复、性能优化

找回密码
注册
搜索
热搜: 活动 交友 discuz
发新帖

0

积分

0

好友

1

主题
1#
发表于 2012-12-28 14:10:39 | 查看: 4064| 回复: 2
本帖最后由 sys 于 2012-12-28 14:22 编辑

问题:不理解子查询是怎样执行的?
其中x表含id/name字段,y表含name字段,z表含id/name字段

server信息:
  1. [oracle@dbalinux ~]$ uname -a
  2. Linux dbalinux.net 2.6.32-300.10.1.el5uek #1 SMP Wed Feb 22 17:37:40 EST 2012 x86_64 x86_64 x86_64 GNU/Linux
复制代码
  1. SQL> select * from v$version;
  2. BANNER
  3. ----------------------------------------------------------------
  4. Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - 64bi
  5. PL/SQL Release 10.2.0.1.0 - Production
  6. CORE        10.2.0.1.0        Production
  7. TNS for Linux: Version 10.2.0.1.0 - Production
  8. NLSRTL Version 10.2.0.1.0 - Production
复制代码
坏境模拟:
  1. SQL> desc x;
  2. Name                                           Null?    Type
  3. ----------------------------------------- -------- ----------------------------
  4. ID                                                    NUMBER
  5. NAME                                                    VARCHAR2(20)

  6. SQL> desc y;
  7. Name                                           Null?    Type
  8. ----------------------------------------- -------- ----------------------------
  9. NAME                                                    VARCHAR2(20)

  10. SQL> desc z;
  11. Name                                           Null?    Type
  12. ----------------------------------------- -------- ----------------------------
  13. ID                                                    NUMBER
  14. NAME                                                    VARCHAR2(20)
复制代码
  1. SQL> select * from x;

  2.         ID NAME
  3. ---------- --------------------
  4.          1 clark
  5.          2 dave
  6.          3 ben

  7. SQL> select * from y;

  8. NAME
  9. --------------------
  10. scott
  11. clark

  12. SQL> select * from z;

  13.         ID NAME
  14. ---------- --------------------
  15.          1 clark
  16.          2 dave
  17.          4 mark
复制代码
  1. SQL> select * from x where x.id in(select id from y);

  2.         ID NAME
  3. ---------- --------------------
  4.          1 clark
  5.          2 dave
  6.          3 ben

  7. SQL> select * from x where x.id in(select id from z);

  8.         ID NAME
  9. ---------- --------------------
  10.          1 clark
  11.          2 dave

  12. SQL> select * from x where x.id in(select y.id from y);
  13. select * from x where x.id in(select y.id from y)
  14.                                      *
  15. ERROR at line 1:
  16. ORA-06553: PLS-306: wrong number or types of arguments in call to 'OGC_Y'


  17. SQL> select * from x where x.id in(select z.id from z);

  18.         ID NAME
  19. ---------- --------------------
  20.          1 clark
  21.          2 dave
复制代码
  1. SQL> select * from x where x.id in(select idd from y);
  2. select * from x where x.id in(select idd from y)
  3.                                      *
  4. ERROR at line 1:
  5. ORA-00904: "IDD": invalid identifier


  6. SQL> select * from x where x.id in(select idd from z);
  7. select * from x where x.id in(select idd from z)
  8.                                      *
  9. ERROR at line 1:
  10. ORA-00904: "IDD": invalid identifier
复制代码
劳烦各位大牛给解答一下为什么select * from x where x.id in(select id from y);的语法检查可以过去?



3#
发表于 2012-12-28 14:28:55

  1. SQL> create table x(id int,name varchar2(200));

  2. Table created.

  3. SQL> create table y(name varchar2(200));

  4. Table created.



  5. SQL> select * from x where x.id  in (select id from y);

  6. no rows selected

  7. SQL> alter system flush shared_pool;      

  8. System altered.

  9. SQL> analyze table x compute statistics;

  10. Table analyzed.

  11. SQL> analyze table y compute statistics;

  12. Table analyzed.

  13. SQL> alter session set events '10053 trace name context forever,level 1';

  14. Session altered.

  15. SQL> select * from x where x.id  in (select id from y);

  16. no rows selected

  17. SQL> oradebug setmypid
  18. Statement processed.
  19. SQL> oradebug tracefile_name
  20. /u01/app/oracle/diag/rdbms/cdb1/cdb1/trace/cdb1_ora_21249.trc














  21. JPPD: Applying transformation directives
  22. query block SEL$1 (#1) unchanged
  23. FPD: Considering simple filter push in query block SEL$1 (#1)
  24. EXISTS (SELECT 0 FROM "Y" "Y")
  25. FPD: Considering simple filter push in query block SEL$2 (#2)
  26. :B1=:B2
  27. try to generate transitive predicate from check constraints for query block SEL$2 (#2)
  28. finally: :B1=:B2

  29. try to generate transitive predicate from check constraints for query block SEL$1 (#1)
  30. finally:  EXISTS (SELECT 0 FROM "Y" "Y")

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


  32. SELECT "X"."ID" "ID", "X"."NAME" "NAME"
  33.   FROM "SYS"."X" "X"
  34. WHERE EXISTS (SELECT 0 FROM "SYS"."Y" "Y" WHERE "X"."ID" = "X"."ID")











  35. 10053 后可以看到

  36. select * from x where x.id  in (select id from y);  实际转换为


  37. SELECT "X"."ID" "ID", "X"."NAME" "NAME"
  38.   FROM "SYS"."X" "X"
  39. WHERE EXISTS (SELECT 0 FROM "SYS"."Y" "Y" WHERE "X"."ID" = "X"."ID")
复制代码
即Oracle实际把select id from y这里的ID 理解为 X.ID,因为这个字段标示 仅在X表上有, 当指定Y.ID时因为实际Y表上不存在该字段所以报        ORA-00904错误

回复 只看该作者 道具 举报

2#
发表于 2012-12-28 14:15:30
自己查的一些资料,Oracle® Database SQL Reference  10 g Release 2 (10.2)  B14200-02
If columns in a subquery have the same name as columns in the containing statement,
then you must prefix any reference to the  column of the table from the containing
statement with the table name or alias. To make your statements easier to read, always
qualify the columns in a subquery with the name or alias of the table, view, or
materialized view.

回复 只看该作者 道具 举报

您需要登录后才可以回帖 登录 | 注册

QQ|手机版|Archiver|Oracle数据库数据恢复、性能优化

GMT+8, 2024-11-16 06:43 , Processed in 0.047291 second(s), 21 queries .

Powered by Discuz! X2.5

© 2001-2012 Comsenz Inc.

回顶部
TEL/電話+86 13764045638
Email service@parnassusdata.com
QQ 47079569