Warum sollte ein Oracle-Synonym eine andere Anzahl von Zeilen an die zugrunde liegende Tabelle zurückgeben?
Frage
Ich habe eine sehr ungewöhnliche Situation und hoffe, dass jemand etwas Licht ins Dunkel bringen kann.Mein Verständnis eines Oracle-Synonyms ist, dass es sich im Grunde um einen Alias für eine Tabelle in einem anderen Schema handelt.
Wenn ich anhand des Synonyms zähle, werden null Zeilen zurückgegeben.Wenn ich dasselbe in der zugrunde liegenden Tabelle mache, werden 12.000 Zeilen zurückgegeben.
Ich kann mir diese Diskrepanz nicht erklären.Kann jemand helfen?
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
Pläne erklären:
Direkt auf dem Tisch...
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)|
--------------------------------------------------------------------------
Durch das 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)
Synonymkette...
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 /
Richtlinien für die Datenbank werden überprüft...
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
Lösung
Aktualisieren:
Du hast ROW LEVEL SECURITY
ermöglicht.
Die Benutzerfunktion FND_GENERIC_POLICY.GET_PREDICATE
wird jedes Mal aufgerufen, wenn Sie auf die Tabelle zugreifen, und beschränkt den Zugriff auf einige Zeilen.
Je nachdem, wie Sie auf die Tabelle zugreifen, werden unterschiedliche Ergebnisse zurückgegeben:direkt oder über die SYNONYM
.
Sie müssen sich die Funktion ansehen und sehen, was los ist (oder den Funktionstext hier posten).
Andere Tipps
Sind Sie sich da zu 100 % sicher? CS.CS_INCIDENTS_ALL_B
handelt es sich tatsächlich um eine Tabelle und nicht um eine Ansicht?Wenn es sich um eine Ansicht handelt, macht sie möglicherweise etwas ziemlich Ungewöhnliches in ihrer WHERE-Klausel.
select object_type from dba_objects where owner = 'CS' and object_name = 'CS_INCIDENTS_ALL_B'
Stellen Sie sicher, dass es keine anderen Objekte (Ansicht oder Tabelle) im Besitz von APPS mit demselben Namen wie Ihr Synonym gibt.
select object_type,object_name
from dba_objects
where object_name='CS_INCIDENTS_B_SEC'
and owner='APPS'
and object_type!='SYNONYM'