代码之家  ›  专栏  ›  技术社区  ›  Jonathan

为什么Oracle同义词会向基础表返回不同数量的行?

  •  5
  • Jonathan  · 技术社区  · 15 年前

    我有一个非常不寻常的情况,我希望有人能够透露一些线索。我对Oracle同义词的理解是,它基本上是另一个模式中表的别名。

    当我从同义词中进行计数时,它返回零行。当我从基础表中执行相同操作时,它将返回12000行。

    我无法解释这种差异。有人能帮忙吗?

    select * from dba_synonyms
    where synonym_name = 'CS_INCIDENTS_B_SEC';
    
    OWNER  SYNONYM_NAME        TABLE_OWNER  TABLE_NAME          DB_LINK
    ------ ------------------- ------------ ------------------- -------
    APPS   CS_INCIDENTS_B_SEC  CS           CS_INCIDENTS_ALL_B         
    
    
    
    select count(*) from CS.CS_INCIDENTS_ALL_B;
    
    COUNT(*)               
    ---------------------- 
    12549                  
    
    select count(*) from APPS.CS_INCIDENTS_B_SEC;
    
    COUNT(*)               
    ---------------------- 
    0                      
    

    解释计划:

    直接在桌子上…

    EXPLAIN PLAN FOR
    SELECT  *
    FROM    CS.CS_INCIDENTS_ALL_B
    
    PLAN_TABLE_OUTPUT
    --------------------------------------------------------------------------
    | Id  | Operation         | Name               | Rows | Bytes| Cost(%CPU)|
    --------------------------------------------------------------------------
    |   0 | SELECT STATEMENT  |                    | 6056 | 1549K|  122   (3)|
    |   1 |  TABLE ACCESS FULL| CS_INCIDENTS_ALL_B | 6056 | 1549K|  122   (3)|
    --------------------------------------------------------------------------
    

    通过同义词…

    EXPLAIN PLAN FOR
    SELECT  *
    FROM    APPS.CS_INCIDENTS_B_SEC
    
    PLAN_TABLE_OUTPUT
    ---------------------------------------------------------------------------
    | Id  | Operation          | Name               | Rows | Bytes| Cost(%CPU)|
    ---------------------------------------------------------------------------
    |   0 | SELECT STATEMENT   |                    |    1 |  262 |    0   (0)|
    |*  1 |  FILTER            |                    |      |      |           |
    |   2 |   TABLE ACCESS FULL| CS_INCIDENTS_ALL_B | 6056 | 1549K|  122   (3)|
    ---------------------------------------------------------------------------
    
    1 - filter(NULL IS NOT NULL)
    

    同义词链…

    SQL> SELECT  *
      2  FROM    dba_synonyms
      3  START WITH
      4          owner = 'CS'
      5          AND synonym_name = 'CS_INCIDENTS_ALL_B'
      6  CONNECT BY
      7          owner = PRIOR table_owner
      8          AND synonym_name = PRIOR table_name
      9  /
    
    no rows selected
    
    SQL> SELECT  *
      2  FROM    dba_synonyms
      3  START WITH
      4          owner = 'APPS'
      5          AND synonym_name = 'CS_INCIDENTS_B_SEC'
      6  CONNECT BY
      7          owner = PRIOR table_owner
      8          AND synonym_name = PRIOR table_name
      9  /
    

    正在检查数据库上的策略…

    SQL> SELECT *
      2  FROM dba_policies
      3  WHERE OBJECT_NAME = 'CS_INCIDENTS_B_SEC'
      4  /
    
    OBJECT_OWNER  OBJECT_NAME         POLICY_GROUP  POLICY_NAME          
    ------------- ------------------- ------------- -------------------- 
    APPS          CS_INCIDENTS_B_SEC  SYS_DEFAULT   CS_SR_SEC_SR_ACCESS  
    
    
    PF_OWNER  PACKAGE            FUNCTION       SEL INS UPD DEL IDX CHK 
    --------- ------------------ -------------- --- --- --- --- --- --- 
    APPS      FND_GENERIC_POLICY GET_PREDICATE  YES NO  NO  NO  NO  NO  
    
    
    ENABLE STATIC_POLICY POLICY_TYPE  LONG_PREDICATE
    ------ ------------- ------------ --------------
    YES    NO            DYNAMIC      YES
    
    3 回复  |  直到 15 年前
        1
  •  5
  •   Quassnoi    15 年前

    更新:

    你有 ROW LEVEL SECURITY 启用。

    用户功能 FND_GENERIC_POLICY.GET_PREDICATE 每次访问表时调用,并限制对某些行的访问。

    它返回不同的结果,具体取决于您如何访问表:直接或通过 SYNONYM .

    您需要查看函数并查看发生了什么(或在此处发布函数文本)。

        2
  •  0
  •   Adam Paynter    15 年前

    你百分之百确定吗 CS.CS_INCIDENTS_ALL_B 实际上,是一个表而不是视图吗?如果它是一个视图,那么它可能在WHERE子句中做了一些非常不寻常的事情。

    select object_type from dba_objects where owner = 'CS' and object_name = 'CS_INCIDENTS_ALL_B'
    
        3
  •  0
  •   IK.    15 年前

    检查以确保应用程序不拥有与同义词同名的其他对象(视图或表)。

    select object_type,object_name
    from   dba_objects
    where  object_name='CS_INCIDENTS_B_SEC'
    and    owner='APPS'
    and    object_type!='SYNONYM'