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

发布于 2024-07-17 09:24:09 字数 3231 浏览 5 评论 0原文

我遇到了一个非常不寻常的情况,我希望有人能够阐明这一点。 我对 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

I have a very unusual situation that I am hoping someone will be able to shed some light onto. My understanding of an oracle synonym is that it is basically an alias to a table in another schema.

When I do a count from the synonym, it returns zero rows. When I do the same from the underlying table, it returns 12 thousand rows.

I cannot explain this discrepancy. Can anyone help?

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 plans:

Directly on the table...

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)|
--------------------------------------------------------------------------

Through the synonym...

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)

Synonym chain...

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  /

Checking Policies on database...

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

梦幻的心爱 2024-07-24 09:24:09

更新:

您有已启用行级安全性

每次访问表时都会调用用户函数 FND_GENERIC_POLICY.GET_PREDICATE 并限制对某些行的访问。

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

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

Update:

You have ROW LEVEL SECURITY enabled.

The user function FND_GENERIC_POLICY.GET_PREDICATE gets called each time you access the table and limits access to some rows.

It returns different results depending on how do you access the table: directly or through the SYNONYM.

You'll need to look into the function and see what's going on (or post the function text here).

别挽留 2024-07-24 09:24:09

您是否 100% 确定 CS.CS_INCIDENTS_ALL_B 实际上是表而不是视图? 如果它是一个视图,也许它在 WHERE 子句中做了一些相当不寻常的事情。

select object_type from dba_objects where owner = 'CS' and object_name = 'CS_INCIDENTS_ALL_B'

Are you 100% sure that CS.CS_INCIDENTS_ALL_B is, in fact, a table and not a view? If it is a view, perhaps it is doing something rather unusual in its WHERE clause.

select object_type from dba_objects where owner = 'CS' and object_name = 'CS_INCIDENTS_ALL_B'
送舟行 2024-07-24 09:24:09

检查以确保 APPS 拥有的其他对象(视图或表)没有与您的同义词同名。

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

Check to make sure there are no other objects (view or table) owned by APPS with the same name as your synonym.

select object_type,object_name
from   dba_objects
where  object_name='CS_INCIDENTS_B_SEC'
and    owner='APPS'
and    object_type!='SYNONYM'
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文