#sql #oracle #plsql #oracle-sqldeveloper
#sql #Oracle #plsql #oracle-sqldeveloper
Вопрос:
Кажется, у меня общая проблема, но другие решения, похоже, не исправили то, что у меня пошло не так. При выполнении вызова пакета для вызова моих процедур он говорит, что вызов неоднозначен. Я извлекаю данные из одной и той же таблицы и могу убедиться, что выбранные типы переменных отличаются. Итак, почему происходит сбой, когда входные данные явно и являются числом и строкой?
Заголовок пакета
CREATE OR REPLACE PACKAGE shop_query_pkg IS
PROCEDURE shop_lookup_pp
(p_id_input IN bb_shopper.idshopper%TYPE,
p_name_output OUT bb_shopper.idshopper%TYPE,
p_city_output OUT bb_shopper.city%TYPE,
p_state_output OUT bb_shopper.state%TYPE,
p_phone_output OUT bb_shopper.phone%TYPE,
p_email_output OUT bb_shopper.email%TYPE);
PROCEDURE shop_lookup_pp
(p_id_input IN bb_shopper.lastname%TYPE,
p_name_output OUT bb_shopper.idshopper%TYPE,
p_city_output OUT bb_shopper.city%TYPE,
p_state_output OUT bb_shopper.state%TYPE,
p_phone_output OUT bb_shopper.phone%TYPE,
p_email_output OUT bb_shopper.email%TYPE);
END;
/
CREATE OR REPLACE PACKAGE BODY shop_query_pkg IS
PROCEDURE shop_lookup_pp
(p_id_input IN bb_shopper.idshopper%TYPE,
p_name_output OUT bb_shopper.idshopper%TYPE,
p_city_output OUT bb_shopper.city%TYPE,
p_state_output OUT bb_shopper.state%TYPE,
p_phone_output OUT bb_shopper.phone%TYPE,
p_email_output OUT bb_shopper.email%TYPE)
IS
BEGIN
SELECT firstname || lastname AS "Name", city, state, phone, email
INTO p_name_output, p_city_output, p_state_output, p_phone_output, p_email_output
FROM bb_shopper
WHERE idshopper = p_id_input;
END;
PROCEDURE shop_lookup_pp
(p_id_input IN bb_shopper.lastname%TYPE,
p_name_output OUT bb_shopper.idshopper%TYPE,
p_city_output OUT bb_shopper.city%TYPE,
p_state_output OUT bb_shopper.state%TYPE,
p_phone_output OUT bb_shopper.phone%TYPE,
p_email_output OUT bb_shopper.email%TYPE)
IS
BEGIN
SELECT firstname || lastname AS "Name", city, state, phone, email
INTO p_name_output, p_city_output, p_state_output, p_phone_output, p_email_output
FROM bb_shopper
WHERE lastname = p_id_input;
END;
END;
Тело пакета
DECLARE
lv_name_txt VARCHAR2(20);
lv_city_txt VARCHAR2(15);
lv_state_txt VARCHAR2(2);
lv_phone_txt VARCHAR2(12);
lv_email_txt VARCHAR2(15);
BEGIN
shop_query_pkg.shop_lookup_pp(23,lv_name_txt,lv_city_txt,
lv_state_txt,lv_phone_txt,lv_email_txt);
DBMS_OUTPUT.PUT_LINE(lv_name_txt);
DBMS_OUTPUT.PUT_LINE(lv_city_txt);
DBMS_OUTPUT.PUT_LINE(lv_state_txt);
DBMS_OUTPUT.PUT_LINE(lv_phone_txt);
DBMS_OUTPUT.PUT_LINE(lv_email_txt);
shop_query_pkg.shop_lookup_pp('Ratman',lv_name_txt,lv_city_txt,
lv_state_txt,lv_phone_txt,lv_email_txt);
DBMS_OUTPUT.PUT_LINE(lv_name_txt);
DBMS_OUTPUT.PUT_LINE(lv_city_txt);
DBMS_OUTPUT.PUT_LINE(lv_state_txt);
DBMS_OUTPUT.PUT_LINE(lv_phone_txt);
DBMS_OUTPUT.PUT_LINE(lv_email_txt);
END;
Отчет об ошибке
Error report -
ORA-06550: line 8, column 3:
PLS-00307: too many declarations of 'SHOP_LOOKUP_PP' match this call
ORA-06550: line 8, column 3:
PL/SQL: Statement ignored
ORA-06550: line 15, column 3:
PLS-00307: too many declarations of 'SHOP_LOOKUP_PP' match this call
ORA-06550: line 15, column 3:
PL/SQL: Statement ignored
06550. 00000 - "line %s, column %s:n%s"
*Cause: Usually a PL/SQL compilation error.
*Action:
Ответ №1:
Эта ошибка обычно возникает, когда у вас одни и те же типы данных в том же порядке, что и аргументы — когда это происходит, вы, вероятно, объявили имена аргументов по-другому, чтобы указывать их в своих вызовах.
В вашем случае, похоже, это происходит потому, что Oracle должен был бы выполнить неявное преобразование для одного из ваших аргументов, чтобы удовлетворить одну из спецификаций процедуры.
p_name_output OUT bb_shopper.idshopper%TYPE
...
lv_name_txt VARCHAR2(20);
Должен ли тип p_name_output
быть объявлен как другой тип данных (я бы предположил, что idshopper
это числовой тип данных.
Тем не менее, я настоятельно рекомендую переименовать ваш p_id_input
во втором определении для дифференциации lastname
и idshopper
фильтрации. Затем явно используйте эти аргументы в своем вызове.
Комментарии:
1. Хорошо, это, похоже, позволило ему работать. Теперь, чтобы выяснить, почему он не выдает никаких выходных данных СУБД.
2. Убедитесь, что он действительно включен — если вы работаете с sql * plus, вам нужно сначала выполнить
set serveroutput on
. Другим клиентским программам потребуются аналогичные вещи, если они не выполняют это по умолчанию.
Ответ №2:
PL / SQL позволяет перегружать имена подпрограмм и методы типов. Вы можете использовать одно и то же имя для нескольких разных подпрограмм, если их формальные параметры отличаются числом, порядком или семейством типов данных. Для примера перегруженной процедуры в пакете.
Примером может быть:
DECLARE
/* First version takes a DATE parameter. */
FUNCTION value_ok (date_in IN DATE) RETURN BOOLEAN IS
BEGIN
RETURN date_in <= SYSDATE;
END;
/* Вторая версия принимает числовой параметр. */
FUNCTION value_ok (number_in IN NUMBER) RETURN BOOLEAN IS
BEGIN
RETURN number_in > 0;
END;
/ * Третья версия — это процедура! */
PROCEDURE value_ok (number_in IN NUMBER) IS
BEGIN
IF number_in > 0 THEN
DBMS_OUTPUT.PUT_LINE (number_in || 'is OK!');
ELSE
DBMS_OUTPUT.PUT_LINE (number_in || 'is not OK!');
END IF;
END;
Ответ №3:
Как указал Эндрю Сейер, тип данных выходных переменных для процедур в пакете требовал неявного преобразования и был причиной ошибки PS-00307. Преобразование их в явные переменные решает эту проблему.
CREATE OR REPLACE PACKAGE shop_query_pkg IS
PROCEDURE shop_lookup_pp
(p_id_input IN bb_shopper.idshopper%TYPE,
p_name_output OUT VARCHAR2,
p_city_output OUT VARCHAR2,
p_state_output OUT VARCHAR2,
p_phone_output OUT VARCHAR2,
p_email_output OUT VARCHAR2);
PROCEDURE shop_lookup_pp
(p_id_input IN bb_shopper.lastname%TYPE,
p_name_output OUT VARCHAR2,
p_city_output OUT VARCHAR2,
p_state_output OUT VARCHAR2,
p_phone_output OUT VARCHAR2,
p_email_output OUT VARCHAR2);
END;
/
CREATE OR REPLACE PACKAGE BODY shop_query_pkg IS
PROCEDURE shop_lookup_pp
(p_id_input IN bb_shopper.idshopper%TYPE,
p_name_output OUT VARCHAR2,
p_city_output OUT VARCHAR2,
p_state_output OUT VARCHAR2,
p_phone_output OUT VARCHAR2,
p_email_output OUT VARCHAR2)
IS
BEGIN
SELECT firstname || lastname AS "Name", city, state, phone, email
INTO p_name_output, p_city_output, p_state_output, p_phone_output, p_email_output
FROM bb_shopper
WHERE idshopper = p_id_input;
END;
PROCEDURE shop_lookup_pp
(p_id_input IN bb_shopper.lastname%TYPE,
p_name_output OUT VARCHAR2,
p_city_output OUT VARCHAR2,
p_state_output OUT VARCHAR2,
p_phone_output OUT VARCHAR2,
p_email_output OUT VARCHAR2)
IS
BEGIN
SELECT firstname || lastname AS "Name", city, state, phone, email
INTO p_name_output, p_city_output, p_state_output, p_phone_output, p_email_output
FROM bb_shopper
WHERE lastname = p_id_input;
END;
END;
Ответ №4:
когда-нибудь, когда у вас есть в заголовке пакета
function my_function(input_parameter number);
но в теле пакета у вас есть параметры с другим именем! вот так
function my_function(my_paramater number) is
...
begin
....
end;
Заголовок и тело должны иметь одинаковое имя функции или процедуры, одинаковый порядок параметров, одинаковые типы параметров, но также одно и то же имя