web-dev-qa-db-fra.com

La traduction des synonymes ORA-00980 n'est plus valide dans PLSQL

J'ai un synonyme sur une base de données Oracle distante à laquelle je peux accéder en SQL via un lien de base de données, par exemple,

insert into my_table select * from my_synonym@my_database_link;

Si je mets l'instruction ci-dessus dans un bloc PLSQL, elle ne sera pas compilée, donnant le message d'erreur "ORA-00980: la traduction des synonymes n'est plus valide". L'explication standard est la table vers laquelle le synonyme pointe a été supprimée, etc., mais ce n'est pas le cas car l'instruction fonctionne en SQL.

9
D Veloper

Merci à tous ceux qui ont essayé d'aider. Cela s'est avéré être une limitation Oracle:

https://support.Oracle.com/rs?type=doc&id=453754.1

S'APPLIQUE À:

PL/SQL - Version 9.2.0.8 et versions ultérieures Les informations contenues dans ce document s'appliquent à toutes les plateformes. Vérification de la pertinence le 01-avr-2015

SYMPTÔMES

Un bloc PL/SQL échoue avec l'erreur: ORA-00980: la traduction des synonymes n'est plus valide lors de la sélection de données dans une base de données distante. Le code suivant illustre ce problème:

Sur DB3 (créer la table)

CONNECT u3/u3 DROP TABLE tab; Onglet CREATE TABLE (numéro c1); INSÉRER DANS L'onglet VALEURS (1); COMMETTRE;

Sur DB2 (créez un synonyme de la table sur DB3)

CONNECT u2/u2 DROP DATABASE LINK dblink2; CRÉER UN LIEN DE BASE DE DONNÉES dblink2 CONNECTER À u3 IDENTIFIÉ PAR u3 À L'AIDE DE 'EMT102U6'; SELECT * FROM nom_globale @ dblink2; DROP SYNONYM syn2; CRÉER SYNONYM syn2 POUR tab @ dblink2; SELECT * FROM syn2;

Sur DB1 (créez un synonyme du synonyme sur DB2)

CONNECT u1/u1 DROP DATABASE LINK dblink1; CRÉER UN LIEN DE BASE DE DONNÉES dblink1 SE CONNECTER À u2 IDENTIFIÉ PAR u2 À L'AIDE DE 'EMT102W6'; SELECT * FROM nom_globale @ dblink1; DROP SYNONYM syn1; CRÉER SYNONYME syn1 POUR syn2 @ dblink1; SELECT c1 from syn1;

Cela fonctionne en SQL mais échoue lorsqu'il est appelé depuis PL/SQL

DECLARE num NUMBER; COMMENCER SELECT c1 EN num DE syn1; FIN; /

ERREUR à la ligne 4: ORA-06550: ligne 4, colonne 3: PL/SQL: ORA-00980: la traduction des synonymes n'est plus valide ORA-06550: ligne 4, colonne 3: PL/SQL: instruction SQL ignorée

CAUSE

Ce problème a été signalé dans le bogue 2829591 QUERING OF A PL/SQL PROCEDURE IN 9I -> 8I-> 7.3.4, GETTING ORA-980. Ce bogue a été fermé comme "PAS UN BUG" pour les raisons suivantes

PL/SQL ne peut pas demander à la base de données intermédiaire (DB2) de suivre le lien de la base de données pendant la phase de compilation. Par conséquent, pour que ce bloc PL/SQL se compile et s'exécute, les deux liens de base de données dblink1 et dblink2 doivent être définis sur la base de données frontale - DB1. Pendant l'exécution, le lien de la base de données dblink2 sera recherché dans DB2 comme prévu.

SOLUTION

Pour implémenter la solution, veuillez exécuter les étapes suivantes:

  1. Créer un lien de base de données dblink2 sur DB1 pointant vers DB3

SQL> créer un lien de base de données dblink2 se connecter à u3 identifié par u3 en utilisant 'EMT102U6';

  1. Créez et compilez le bloc PL/SQL sur DB1.

CRÉER UN LIEN DE BASE DE DONNÉES dblink2 CONNECTER À u3 IDENTIFIÉ PAR u3 À L'AIDE DE 'EMT102U6';

SELECT * FROM nom_globale @ dblink2; DECLARE num NUMBER; COMMENCER
SELECT c1 INTO num FROM syn1; FIN;/PL/SQL procédure terminée avec succès.

CONSEIL: Une autre option consiste à utiliser SQL dyanmique dans le bloc PL/SQL comme solution de contournement. Lors de l'utilisation de SQL dynamique, le lien de base de données n'est pas résolu au moment de la compilation mais au moment de l'exécution.

2
D Veloper

Si quelque chose fonctionne en SQL mais pas en PL/SQL, alors dans la plupart des cas, c'est un problème de privilèges.

Tout privilège qu'un utilisateur a reçu via un rôle n'est pas actif lorsque vous entrez un bloc PL/SQL. Donc, très probablement, le privilège SELECT sur la table sous-jacente a été accordé via un rôle et n'est donc pas "actif" dans le bloc PL/SQL.

Le remède habituel consiste à accorder les privilèges directement à l'utilisateur, et non via un rôle.

2

La solution de contournement consiste à utiliser une vue Oracle à la place.

CREATE VIEW v_my_synomym as (select * from my_synonym@my_database_link);

Référencez ensuite la vue dans votre package ou procédure, c'est-à-dire:

insert into my_table select * from v_my_synonym;
0
Abdul Majid

L'archivage dans les bases de données distantes pour "mon_synonyme" doit être presque "sélectionner" pour l'utilisateur que vous utilisez dans la chaîne de connexion, vérifiez également l'objet vers lequel ce synonyme pointe (peut-être que quelqu'un a supprimé la table).

0
NavyPier

J'ai trouvé ce problème lorsque le propriétaire de la table/vue/procédure ne correspond pas au propriétaire mentionné dans SYNONYM.

Exemple: si le propriétaire de la table TABLE_BRACH est propriétaireA et dans le synonyme le propriétaire de table mentionné est autre chose (pas propriétaireA).

Solution: 1. Déposez le SYNONYM 2. Créez-le avec le même nom avec le bon propriétaire.

CREATE PUBLIC SYNONYM BRANCH FOR ownerA.TABLE_BRACH ;
0
Md. Kamruzzaman