您的位置:首页 > 数据库 > Oracle

Oracle EBS R12 - 查询同一个表在不同用户下的同义词(XLA_TRANSACTION_ENTITIES)时返回的结果不一样

2013-09-13 21:22 786 查看
Oracle EBS R12 - 查询同一个表在不同用户下的同义词(XLA_TRANSACTION_ENTITIES)时返回的结果不一样

在EBS R12系统中有张表"XLA"."XLA_TRANSACTION_ENTITIES",并且同时存在APPS和APPSREAD针对该表的同义词,
定义如下:
CREATE OR REPLACE SYNONYM "APPS"."XLA_TRANSACTION_ENTITIES" FOR "XLA"."XLA_TRANSACTION_ENTITIES";
CREATE OR REPLACE SYNONYM "APPSREAD"."XLA_TRANSACTION_ENTITIES" FOR "XLA"."XLA_TRANSACTION_ENTITIES";

但是针对同义词相同条件的查询返回的结果却不一样:
SQL> select count(*) from apps.XLA_TRANSACTION_ENTITIES where application_id=222;

COUNT(*)
----------
1

SQL> select count(*) from appsread.XLA_TRANSACTION_ENTITIES where application_id=222;

COUNT(*)
----------
112884

SQL>

看到这个问题首先想到就是用trace跟踪一下:
SQL> set autotrace traceonly explain
SQL> select count(*) from apps.XLA_TRANSACTION_ENTITIES where application_id=222;

Execution Plan
----------------------------------------------------------
Plan hash value: 2139858008

-------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | Pstart| Pstop |
-------------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 8 | 481 (2)| 00:00:06 | | |
| 1 | SORT AGGREGATE | | 1 | 8 | | | | |
| 2 | PARTITION LIST SINGLE| | 1 | 8 | 481 (2)| 00:00:06 | KEY | KEY |
|* 3 | TABLE ACCESS FULL | XLA_TRANSACTION_ENTITIES | 1 | 8 | 481 (2)| 00:00:06 | 2 | 2 |
-------------------------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

3 - filter("SECURITY_ID_INT_1" IS NULL)

SQL> select count(*) from appsread.XLA_TRANSACTION_ENTITIES where application_id=222;

Execution Plan
----------------------------------------------------------
Plan hash value: 1648015674

----------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | Pstart| Pstop |
----------------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 4 | 331 (1)| 00:00:04 | | |
| 1 | SORT AGGREGATE | | 1 | 4 | | | | |
| 2 | PARTITION LIST SINGLE| | 112K| 438K| 331 (1)| 00:00:04 | KEY | KEY |
|* 3 | INDEX FULL SCAN | XLA_TRANSACTION_ENTITIES_U1 | 112K| 438K| 331 (1)| 00:00:04 | 2 | 2 |
----------------------------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

3 - access("APPLICATION_ID"=222)

SQL>

trace告诉了我们真相,实际查询时二者的条件完全不一样:
apps使用的是: filter("SECURITY_ID_INT_1" IS NULL)和("APPLICATION_ID"=222),不过后者用来定位表的分区了
appsread使用的是:access("APPLICATION_ID"=222)

当我们把filter("SECURITY_ID_INT_1" IS NULL)加到appsread查询上时,得到了和apps相同的结果:
SQL> set autotrace on
SQL> select count(*) from appsread.XLA_TRANSACTION_ENTITIES where application_id=222 and ("SECURITY_ID_INT_1" IS NULL);

COUNT(*)
----------
1

Execution Plan
----------------------------------------------------------
Plan hash value: 2139858008

-------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | Pstart| Pstop |
-------------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 8 | 481 (2)| 00:00:06 | | |
| 1 | SORT AGGREGATE | | 1 | 8 | | | | |
| 2 | PARTITION LIST SINGLE| | 1 | 8 | 481 (2)| 00:00:06 | KEY | KEY |
|* 3 | TABLE ACCESS FULL | XLA_TRANSACTION_ENTITIES | 1 | 8 | 481 (2)| 00:00:06 | 2 | 2 |
-------------------------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

3 - filter("SECURITY_ID_INT_1" IS NULL)

Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
1661 consistent gets
0 physical reads
0 redo size
335 bytes sent via SQL*Net to client
350 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
1 rows processed

SQL>

为什么apps会多出一个我们没有指定的条件呢?这其实是Oracle VPD自动加上去的,
类似你要查询oe_order_headers的数据时要先调用fnd_global初始化ORG_ID,
有关VPD可以参考另一篇blog:
利用Oracle VPD(虚拟专用数据库)实现类似EBS R12里的多OU屏蔽 http://blog.csdn.net/t0nsha/article/details/7423638
SQL> SELECT object_owner,object_name,pf_owner,package,function,sel FROM dba_policies where object_name = 'XLA_TRANSACTION_ENTITIES';

OBJECT_OWNER                   OBJECT_NAME                    PF_OWNER                       PACKAGE                FUNCTION                       SEL
------------------------------ ------------------------------ ------------------------------ ------------------------------ ------------------------------ ---
APPS                           XLA_TRANSACTION_ENTITIES       APPS                           XLA_SECURITY_POLICY_PKG        MO_POLICY                      YES
APPS                           XLA_TRANSACTION_ENTITIES       APPS                           XLA_SECURITY_POLICY_PKG        MO_POLICY                      YES
APPS                           XLA_TRANSACTION_ENTITIES       APPS                           XLA_SECURITY_POLICY_PKG        MO_POLICY                      YES
APPS                           XLA_TRANSACTION_ENTITIES       APPS                           XLA_SECURITY_POLICY_PKG        XLA_STANDARD_POLICY            YES
APPS                           XLA_TRANSACTION_ENTITIES       APPS                           XLA_SECURITY_POLICY_PKG        MO_POLICY                      YES
APPS                           XLA_TRANSACTION_ENTITIES       APPS                           XLA_SECURITY_POLICY_PKG        MO_POLICY                      YES
APPS                           XLA_TRANSACTION_ENTITIES       APPS                           XLA_SECURITY_POLICY_PKG        MO_POLICY                      YES

7 rows selected.

SQL>


知道了原因,我们试着给APPSREAD用户也增加APPS相似的policy,看看结果怎样:
SQL> BEGIN
2 DBMS_RLS.add_policy (object_schema => 'APPSREAD'
3 ,object_name => 'XLA_TRANSACTION_ENTITIES'
4 ,policy_name => 'APPSREAD_policy'
5 ,function_schema => 'APPS'
6 ,policy_function => 'XLA_SECURITY_POLICY_PKG.MO_POLICY'
7 ,statement_types => 'SELECT');
8 END;
9 /

PL/SQL procedure successfully completed.

SQL>

SQL> SELECT object_owner,object_name,policy_name,policy_group,pf_owner,package,function,sel FROM dba_policies where object_name = 'XLA_TRANSACTION_ENTITIES';

OBJECT_OWN OBJECT_NAME                    POLICY_NAME                    POLICY_GROUP    PF_OW PACKAGE                        FUNCTION                       SEL
---------- ------------------------------ ------------------------------ --------------- ----- ------------------------------ ------------------------------ ---
APPS       XLA_TRANSACTION_ENTITIES       PA_SECURITY_POLICY             PA              APPS  XLA_SECURITY_POLICY_PKG        MO_POLICY                      YES
APPS       XLA_TRANSACTION_ENTITIES       DPP_SECURITY_POLICY            DPP             APPS  XLA_SECURITY_POLICY_PKG        MO_POLICY                      YES
APPS       XLA_TRANSACTION_ENTITIES       OKL_SECURITY_POLICY            OKL             APPS  XLA_SECURITY_POLICY_PKG        MO_POLICY                      YES
APPS       XLA_TRANSACTION_ENTITIES       XLA_SECURITY_POLICY            XLA             APPS  XLA_SECURITY_POLICY_PKG        XLA_STANDARD_POLICY            YES
APPS       XLA_TRANSACTION_ENTITIES       IGC_SECURITY_POLICY            IGC             APPS  XLA_SECURITY_POLICY_PKG        MO_POLICY                      YES
APPS       XLA_TRANSACTION_ENTITIES       SQLAP_SECURITY_POLICY          SQLAP           APPS  XLA_SECURITY_POLICY_PKG        MO_POLICY                      YES
APPS       XLA_TRANSACTION_ENTITIES       AR_SECURITY_POLICY             AR              APPS  XLA_SECURITY_POLICY_PKG        MO_POLICY                      YES
APPSREAD   XLA_TRANSACTION_ENTITIES       APPSREAD_POLICY                SYS_DEFAULT     APPS  XLA_SECURITY_POLICY_PKG        MO_POLICY                      YES

8 rows selected.

SQL>


设置了和APPS相同的policy后,APPSREAD获得了和APPS用户相同的查询结果:
SQL> set autotrace on;
SQL> select count(*) from appsread.XLA_TRANSACTION_ENTITIES where application_id=222;

COUNT(*)
----------
1

Execution Plan
----------------------------------------------------------
Plan hash value: 2139858008

-------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | Pstart| Pstop |
-------------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 8 | 481 (2)| 00:00:06 | | |
| 1 | SORT AGGREGATE | | 1 | 8 | | | | |
| 2 | PARTITION LIST SINGLE| | 1 | 8 | 481 (2)| 00:00:06 | KEY | KEY |
|* 3 | TABLE ACCESS FULL | XLA_TRANSACTION_ENTITIES | 1 | 8 | 481 (2)| 00:00:06 | 2 | 2 |
-------------------------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

3 - filter("SECURITY_ID_INT_1" IS NULL)

Statistics
----------------------------------------------------------
2 recursive calls
0 db block gets
1661 consistent gets
0 physical reads
0 redo size
335 bytes sent via SQL*Net to client
350 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
1 rows processed

SQL>

综上可以看出,如果DBMS_RLS.add_policy作用于同义词时,则只对在该过程的object_schema参数中指定的用户下的同义词有效。

最后删除policy,恢复环境:
SQL> exec DBMS_RLS.DROP_POLICY(object_schema=>'APPSREAD',object_name=>'XLA_TRANSACTION_ENTITIES',policy_name=>'APPSREAD_policy');

PL/SQL procedure successfully completed.

SQL>

REF:
1. Using Oracle Virtual Private Database to Control Data Access http://docs.oracle.com/cd/B28359_01/network.111/b28531/vpd.htm
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐