Перевод синонимов ORA-00980 больше не действителен в PLSQL

У меня есть синоним удаленной базы данных Oracle, к которой я могу получить доступ в SQL по ссылке базы данных, например,

insert into my_table select * from my_synonym@my_database_link;

Если я помещу вышеуказанный оператор в блок PLSQL, он не будет компилироваться, давая сообщение об ошибке "ORA-00980: перевод синонимов больше не действителен". Стандартное объяснение-это таблица, на которую указывает синоним, и т. д., Но это не так, потому что оператор работает в SQL.

4 ответов


если что-то работает в SQL, но не в PL/SQL, то в большинстве случаев это проблема с привилегиями.

любые привилегии, которые пользователь получил через роль не активен при вводе блока PL/SQL. Так что, скорее всего,SELECT привилегия в базовой таблице была предоставлена через роль и, таким образом, не является "активной" в блоке PL/SQL.

обычным средством для этого является предоставление привилегий непосредственно пользователю, а не через роль.


спасибо всем, кто пытался помочь. Это оказалось ограничением Oracle:

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

ОТНОСИТСЯ К:

PL / SQL-версия 9.2.0.8 и более поздние сведения в этом документе применяется к любой платформе. проверено на актуальность 01-апр-2015

симптомы

блок PL / SQL завершается ошибкой: ORA-00980: перевод синонимов отсутствует больше допустимо при выборе данных из удаленной базы данных. Этот следующий код демонстрирует эту проблему:

на DB3 (создать таблицу)

подключить вкладку таблицы U3 / U3; создать вкладку таблицы (Номер c1); вставить В значения табуляции (1); COMMIT;

в DB2 (создайте синоним таблицы в DB3)

CONNECT U2 / U2 падение базы данных ссылка dblink2; создать ссылку базы данных DBLINK2 подключение к u3 Идентифицировано u3 с помощью 'EMT102U6'; выберите * От global_name@dblink2; падение синоним syn2; создать синоним syn2 Для вкладки@dblink2; выберите * из syn2;

на DB1 (создайте синоним к синониму на DB2)

CONNECT U1 / U1 падение базы данных ссылка dblink1; создать ссылку базы данных dblink1 подключиться к У2 определены У2, используя 'EMT102W6'; выберите * Из global_name@dblink1; падение синоним syn1-генератор; создать синоним syn1-генератор Для syn2@dblink1; выберите c1 из syn1-генератор;

Это работает в SQL, но не выполняется при вызове из PL / SQL

объявить номер num; начать выбор c1 в num из syn1; конец; /

ошибка в строке 4: ORA-06550: строка 4, столбец 3: PL / SQL: ORA-00980: перевод синонимов больше не действителен ORA-06550: строка 4, столбец 3: PL / SQL: оператор SQL игнорируется

причина

эта проблема была сообщена в ошибке 2829591 QUERING из PL / SQL ПРОЦЕДУРА В 9I - > 8I-> 7.3.4, ПОЛУЧЕНИЕ ORA-980. Эта ошибка была закрыта как "не ошибка" по следующим причинам

PL / SQL не может инструктировать среднюю базу данных (DB2) следовать за базой данных ссылка на этапе компиляции. Поэтому для этого PL / SQL блок для компиляции и запуска, обе ссылки базы данных dblink1 и dblink2 должно быть определено на интерфейсной базе данных-DB1. Во время выполнения ссылка на базу данных dblink2 будет найдена в DB2, как и ожидалось.

решение

чтобы реализовать решение, выполните следующие действия:

  1. создайте ссылку базы данных dblink2 на DB1, указывающую на DB3

SQL> создать ссылку на базу данных dblink2 подключиться к u3, идентифицированной u3 с помощью 'EMT102U6';

  1. создайте и скомпилируйте блок PL/SQL на DB1.

создать ссылку на базу данных DBLINK2 подключиться к u3, идентифицированной u3 с помощью 'EMT102U6';

выбрать * из global_name@dblink2; объявить num NUMBER; BEGIN
Выберите c1 в num из процедуры syn1; END;/PL / SQL успешно завершенный.

совет: другой вариант-использовать dyanmic SQL в блоке PL / SQL в качестве обходной. При использовании динамического SQL ссылка на базу данных не разрешена во время компиляции, но во время выполнения.


Проверьте гранты удаленной базы данных для " my_synonym "должны быть почти" select " для пользователя, которого вы используете в строке подключения, проверьте также объект, на который указывает этот синоним (возможно, кто-то удалил таблицу).


Я нашел эту проблему, когда владелец таблицы/представления / процедуры не совпадает с владельцем, упомянутым в синониме.

пример: если владельцем таблицы TABLE_BRACH является ownerA, а в синониме упомянутый владелец таблицы-что-то другое (не ownerA).

решение: 1. Капли синоним 2. Создайте это с тем же именем с правильным владельцем.

CREATE PUBLIC SYNONYM BRANCH FOR ownerA.TABLE_BRACH ;