Perché un sinonimo di Oracle restituire un diverso numero di righe alla tabella sottostante?
Domanda
Ho una situazione molto particolare che sto sperando che qualcuno sarà in grado di far luce su. La mia comprensione di un sinonimo di Oracle è che è fondamentalmente un alias ad una tabella in un altro schema.
Quando faccio un conteggio dal sinonimo restituisce zero righe. Quando faccio la stessa dalla tabella sottostante, restituisce 12 mila righe.
Non riesco a spiegare questa discrepanza. Chiunque può aiutare?
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
Spiegare i piani:
Direttamente sul tavolo ...
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)|
--------------------------------------------------------------------------
Con il sinonimo ...
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)
catena Sinonimo ...
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 /
Controllo Politiche relative ai 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
Soluzione
Aggiornamento:
Hai ROW LEVEL SECURITY
enabled.
L'FND_GENERIC_POLICY.GET_PREDICATE
funzione utente viene chiamata ogni volta che si accede al tavolo e limita l'accesso ad alcune righe.
Si restituisce i risultati diversi a seconda di come si fa a accedere alla tabella: direttamente o tramite l'SYNONYM
È necessario esaminare la funzione e vedere cosa sta succedendo (o inviare il testo della funzione qui).
Altri suggerimenti
Sei sicuro al 100% che CS.CS_INCIDENTS_ALL_B
è, di fatto, un tavolo e non una vista? Se si tratta di una visione, forse sta facendo qualcosa di piuttosto insolito nella sua clausola WHERE.
select object_type from dba_objects where owner = 'CS' and object_name = 'CS_INCIDENTS_ALL_B'
Controllare per assicurarsi che non vi siano altri oggetti (vista o da tavolo) di proprietà APPS con lo stesso nome del sinonimo.
select object_type,object_name
from dba_objects
where object_name='CS_INCIDENTS_B_SEC'
and owner='APPS'
and object_type!='SYNONYM'