Вопрос:
Я подключаюсь к базе данных Oracle как user1. Внутри базы данных существует user2 и имеет пакет pack1, который содержит две хранимые процедуры, proc1 и proc2.
Я пытаюсь вызвать эти процедуры, но я получаю вышеупомянутую ошибку. В ошибке упоминается “type1” , который определен в “Типы”.
После некоторых исследований было предложено проверить привилегии, однако, похоже, все в порядке. Я использую Oracle SQL Developer, и когда я нажимаю “гранты” на pack1 и type1, у моего пользователя есть привилегии EXECUTE и DEBUG.
Я думал, что это ошибка в коде, но это вызовет другую ошибку. Я думал о создании синонима для пакета, поскольку я прочитал, что это может помочь, но у меня нет необходимости делать это, и, прежде чем я спрошу, я хотел исчерпать все мои варианты.
Я попытался использовать как мой подготовленный вызов, так и стандартный, созданный SQL Developer, когда я пытаюсь запустить эти хранимые процедуры. Интересно, что когда я запускаю свой код, указанная ошибка вызывается. Когда я запускаю код “по умолчанию”, я получаю ошибку “Относительный путь в абсолютном URI”.
Есть ли что-нибудь, что я мог пропустить?
Это код, который я использую для вызова процедуры.
DECLARE ClientData type1; BEGIN pack1.proc1(param1,param2,ClientData); FOR i IN 1..ClientData.LAST LOOP DBMS_OUTPUT.PUT_LINE(ClientData(i).kid ||’ ‘…; —DBMS_OUTPUT.PUT_LINE(ClientData(i).portfolioName); —DBMS_OUTPUT.PUT_LINE(ClientData(i).clientCategory); —DBMS_OUTPUT.PUT_LINE(ClientData(i).typ_pf); —DBMS_OUTPUT.PUT_LINE(ClientData(i). ptf_ccy); END LOOP; END;
EDIT 1: вот полная ошибка:
ORA-06550: row 2, column 14: PLS-00201: identifier ‘SYSADMIN(user2).CLIENTDATAINSTRESB_A(type1)’ must be declared ORA-06550: row 2, column 14: PL/SQL: Item ignored ORA-06550: row 4, column 53: PLS-00320: the declaration of the type of this expression is incomplete or malformed ORA-06550: row 4, column 1: PL/SQL: Statement ignored ORA-06550: row 5, column 13: PLS-00320: the declaration of the type of this expression is incomplete or malformed ORA-06550: row 5, column 1: PL/SQL: Statement ignored 06550. 00000 — «line %s, column %s:n%s» *Cause: Usually a PL/SQL compilation error. *Action:
В нормальных условиях я бы включил тело процедуры, однако это бизнес, и поэтому я не могу поделиться.
Из того, что я понимаю, в начале вызова объявление не выполняется, и поэтому оно приводит к остальным ошибкам, поскольку они соответствуют местам, где вызывается “type1” .
Чтобы дополнительно объяснить, что такое “type1” , это является ссылкой на таблицу ( “тип2” ). Он создается следующим кодом:
create or replace TYPE type1 IS TABLE OF type2;
ИЗМЕНИТЬ 2
как предложил @Alex Poole, я изменил свое выражение:
DECLARE ClientData user2.type1;
однако он воспроизвел ту же ошибку:
PLS-00201: identifier ‘user2.type1’ must be declared
ИЗМЕНИТЬ 3
Неправильные имена были вызваны тем, что я сбрасывал стерилизацию кода, это было исправлено.
Пакеты и оба типа принадлежат пользователю2. Когда я подключаюсь к базе данных, я не вижу ничего с моей точки зрения. Нет таблиц, пакетов или типов. Только когда я просматриваю “Другие пользователи” и смотрю в перспективе пользователя2, я могу видеть требуемые процедуры.
Кроме того, я уверен, что у меня есть привилегии (EXECUTE и DEBUG) для всех необходимых объектов. Это пакеты и определенные типы.
Говоря о том, как были предоставлены привилегии, есть ли способ проверить это? Я использовал команду
SELECT * FROM USER_TAB_PRIVS;
Он перечисляет user2 в качестве Концедента и Владельца и пользователя1 в качестве гранта
EDIT 4
Это результат SELECT * FROM USER_TAB_PRIVS;
GRANTEE OWNER TABLE_NAME GRANTOR PRIVILEGE GRANTABLE HIERARCHY COMMON TYPE USER1 USER2 TYPE2 USER2 DEBUG NO NO NO TYPE USER1 USER2 TYPE2 USER2 EXECUTE NO NO NO TYPE USER1 USER2 TYPE1 USER2 DEBUG NO NO NO TYPE USER1 USER2 TYPE1 USER2 EXECUTE NO NO NO TYPE USER1 USER2 PACK1 USER2 DEBUG NO NO NO PACKAGE USER1 USER2 PACK1 USER2 EXECUTE NO NO NO PACKAGE PUBLIC SYS USER1 USER1 INHERIT PRIVILEGES NO NO NO USER
РЕДАКТИРОВАТЬ 5: Исправлена таблица результатов с нижнего регистра на верхний регистр. Однако, как было предложено, я дважды проверял имена пакета и Типы, они действительно в верхнем регистре.
Ответ №1
Я думаю, что основная проблема – это определение типов.
Вы должны проверить, какой тип используется в строке.
Что вы должны иметь:
user1 → NO TYPES, пакет, который вызывает user2-stuff
user2 → Type1, Pack1, Proc1
Пример:
— Create your type on schema user2 CREATE OR REPLACE TYPE USER2.TestType AS OBJECT ( NEWATTRIB1 VARCHAR2(1000) ) / — Create your package at user2 CREATE OR REPLACE PACKAGE user2.TestPackage AS FUNCTION MyFunction(Param1 IN TestType) RETURN TestType; END TestPackage; / CREATE OR REPLACE PACKAGE BODY user2.TestPackage AS FUNCTION MyFunction(Param1 IN TestType) RETURN TestType IS BEGIN RETURN Param1; END; END TestPackage; / — Grant rights user1 (run with user2) GRANT ALL ON TestType TO User1 WITH GRANT OPTION; GRANT EXECUTE ON TestPackage TO User1 WITH GRANT OPTION; — Call proc from User1 declare tmp USER2.TestType; tmp2 USER2.TestType; begin tmp := USER2.TestType(‘Mr.Smith’); tmp2 := USER2.TESTPACKAGE.MYFUNCTION(tmp); dbms_output.put_line(‘tmp: ‘ || tmp.NEWATTRIB1); dbms_output.put_line(‘tmp2: ‘ || tmp2.NEWATTRIB1); end;
Пожалуйста, помните:
Два типа никогда не бывают одинаковыми! Если вы используете тип в схеме, вам не разрешается определять аналогичный тип в другой схеме для извлечения объекта. Вы должны явно указать тип в другой схеме (= user2.type1).
Вы должны предоставить права на схему/пользователя, который хочет использовать этот тип (в вашем примере введите тип и пакет-привилегии).
Как устранение неполадок в существующем проекте, вы можете проверить его шаг за шагом:
- Вход в систему с пользователем1
-
Напишите некоторый plsql, который использует ваш тип
declare tmp user2.type1; begin tmp := user2.type1(‘Mr.Smith’); — if this works, your type-privs are correct. end;
-
Напишите некоторый plsql, который использует пакет