ORA-00904 Ошибка "неверный идентификатор" при использовании "MERGE INTO" и "SELECT FROM dual" в столбце DATE
У меня есть следующая хранимая процедура PL/SQL в базе данных Oracle:
PROCEDURE MyProcedure (
p_id IN NUMBER
, p_date IN DATE
, p_num IN NUMBER)
AS
BEGIN
MERGE INTO MY_TABLE mytable
USING (SELECT
p_id,
p_date,
p_num
FROM dual) temp
ON (mytable.myid = temp.p_id AND mytable.mydate = temp.p_date)
WHEN MATCHED THEN
UPDATE SET
DIFFERENCE = temp.p_num,
WHEN NOT MATCHED THEN
INSERT VALUES (
MY_TABLEIDSEQ.NEXTVAL,
temp.p_id,
temp.p_date,
temp.p_num);
END MyProcedure;
Таблица MY_TABLE определяется следующим образом:
CREATE TABLE "MY_DBO"."MY_TABLE"
(
"MYTABLEID" NUMBER(38,0),
"MYID" NUMBER(38,0),
"MYDATE" DATE,
"MYNUM" NUMBER(25,4)
)
Однако, когда я запускаю хранимую процедуру с допустимыми значениями для полей ввода, я получаю следующую ошибку:
ORA-00904: "TEMP". "P_DATE": неверный идентификатор
ORA-06512: на "MY_DBO.MY_PKG", строка 54
ORA-06512: в строке 18
Я понятия не имею, что вызывает это, любая помощь будет принята с благодарностью. Обратите внимание, что хранимая процедура начинается в строке 45 MY_PKG.
Я нашел подобную проблему здесь, но решение изменить "двойной" на "MY_TABLE", похоже, не сработало для меня.
PS: я очень плохо знаком с Oracle:)
2 ответа
В операторе "выбрать из двойного" вы использовали входные параметры ваших хранимых процедур в качестве значений. Oracle действительно генерирует неявные имена для этих столбцов, которые я пока не могу предсказать. Но вы можете указать свои собственные имена столбцов / псевдонимов в этом выражении:
USING (SELECT
p_id col_id,
p_date col_date,
p_num col_num
FROM dual) temp
Эти имена являются лишь примерами. Я настоятельно рекомендую вам использовать уникальные имена в таком случае, чтобы не допустить двусмысленности в дальнейшем. Вам нужно будет заменить любое использование temp.* В вашем операторе слияния указанными вами псевдонимами.
Это на самом деле не ответит на ваш вопрос, поскольку на него уже ответил Юрген Хартелт, но предоставит вам дополнительную информацию.
Поскольку вы вставляете или обновляете здесь только одну строку, другим вариантом может быть отказ от использования MERGE
и использовать комбинацию INSERT
а также UPDATE
вместо.
В вашем случае вы бы использовали
PROCEDURE MyProcedure (
p_id IN NUMBER
, p_date IN DATE
, p_num IN NUMBER)
AS
BEGIN
Update MY_TABLE mytable
Set MYNUM = p_num
Where mytable.MYID = p_id AND mytable.MYDATE = p_date;
If SQL%ROWCOUNT = 0 then
INSERT INTO MY_TABLE mytable
Values (MY_TABLEIDSEQ.NEXTVAL,
temp.p_id,
temp.p_date,
temp.p_num);
END IF;
END MyProcedure;
Также, возможно, стоит посмотреть на вопрос " Как сделать UPSERT", так как он предоставит вам полное меню опций для решения этой проблемы.