Я подключаюсь к базе данных 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: Исправлена таблица результатов с нижнего регистра на верхний регистр. Однако, как было предложено, я дважды проверял имена пакета и Типы, они действительно в верхнем регистре.
Я думаю, что основная проблема – это определение типов.
Вы должны проверить, какой тип используется в строке.
Что вы должны иметь:
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, который использует пакет