ORA-00904 在 DATE 列上使用“MERGE INTO”和“SELECT FROM dual”时出现“无效标识符”错误
Posted
技术标签:
【中文标题】ORA-00904 在 DATE 列上使用“MERGE INTO”和“SELECT FROM dual”时出现“无效标识符”错误【英文标题】:ORA-00904 'invalid identifier' error using 'MERGE INTO' and 'SELECT FROM dual' on a DATE column 【发布时间】:2012-06-13 16:54:21 【问题描述】:我在 Oracle 数据库上有以下 PL/SQL 存储过程:
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 行
我不知道是什么原因造成的,任何帮助将不胜感激。请注意,存储过程从 MY_PKG 的第 45 行开始。
我发现了一个类似的问题 here,但将“dual”更改为“MY_TABLE”的解决方案似乎对我不起作用。
PS:我对 Oracle 很陌生 :)
【问题讨论】:
【参考方案1】:在“select from dual”语句中,您使用了存储过程的输入参数作为值。 Oracle 确实为这些列生成了隐式名称,我目前无法预测。但是您可以在该语句中提供您自己的列名/别名:
USING (SELECT
p_id col_id,
p_date col_date,
p_num col_num
FROM dual) temp
这些名称只是示例。我强烈建议您在这种情况下使用唯一名称,以防止以后出现任何歧义。 您需要用您提供的别名替换合并语句中对 temp.* 的任何使用。
【讨论】:
【参考方案2】:这不会真正回答您的问题,因为 Juergen Hartelt 已经回答了它,但它会为您提供更多信息。
由于您只在此处插入或更新一行,另一种选择可能是放弃使用 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;
此外,“How to UPSERT”问题可能值得一看,因为它会为您提供解决此问题的完整选项菜单。
【讨论】:
“如何 UPSERT”链接上接受的答案实际上建议使用 MERGE ...?无论如何,我实际上是使用 ODP.NET 通过这个存储过程添加多行: void Foo(OracleCommand command, IDbOperation operation) var param = command.CreateParameter(); param.ParameterName = "p_myParam"; param.Value = new int[] 1, 2, 3 ;参数.OracleDbType = OracleDbType.Int32; param.Direction = ParameterDirection.Input; command.Parameters.Add(param); command.ArrayBindCount = 3;操作.执行();以上是关于ORA-00904 在 DATE 列上使用“MERGE INTO”和“SELECT FROM dual”时出现“无效标识符”错误的主要内容,如果未能解决你的问题,请参考以下文章