【问题标题】:Oracle: Invalid identifier甲骨文:无效的标识符
【发布时间】:2016-06-08 13:53:13
【问题描述】:

我在 oracle 中使用以下查询。但是,它给出了一个错误,指出第 5 行中的“c.par”是一个无效参数。不知道为什么。列存在。我检查了。我已经为此苦苦挣扎了很长时间。我要做的就是将一个表合并到另一个表中并使用 oracle 更新它。有人可以帮忙吗?

MERGE INTO SPRENTHIERARCHIES 
USING ( SELECT c.PARENTCATEGORYID AS par,  
             e.rootcategoryId AS root 
        FROM  SPRENTCATEGORIES c,SPRENTHIERARCHIES e 
        WHERE e.root (+)= c.par 
      ) SPRENTCATEGORIES  
ON (SPRENTHIERARCHIES.rootcategoryId = SPRENTCATEGORIES.parentcategoryId) 
WHEN MATCHED THEN 
UPDATE SET e.root=c.par 

【问题讨论】:

  • 您的查询实际上没有意义。你为什么用merge而不是简单的update
  • 那么错误是“无效标识符”还是“无效参数”?在这两种情况下,它都没有关联的 ORA 代码吗?
  • 除非您的 SPRENTHIERARCHIES 表同时具有 rootcategoryIdroot 列,并且您的 SPRENTCATEGORIES 表同时具有 parentCategoryIdpar 列,否则您检查是否存在错误名称。也许将表定义添加到问题中以澄清。但这似乎并没有真正做任何事情,如果匹配的话,你会更新到相同的值。

标签: oracle sql-merge


【解决方案1】:

ec 别名仅存在于 using 子句的查询中。您试图在 update 子句中引用它们。您还针对没有该列的目标表使用来自 using 子句的列别名(除非您的表同时具有 rootcategoryId 和 root,以及 parentCategoryId 和 par)。

所以这个:

UPDATE SET e.root=c.par 

应该是:

UPDATE SET SPRENTHIERARCHIES.rootcategoryId= SPRENTCATEGORIES.par 

using 子句中,您尝试使用列别名作为同一级别的查询,因此:

    WHERE e.root (+)= c.par 

应该是:

    WHERE e.rootcategoryId (+)= c.PARENTCATEGORYID

您的on 子句也是错误的,因为那是 使用列别名:

ON (SPRENTHIERARCHIES.rootcategoryId = SPRENTCATEGORIES.par) 

但我建议您将 using 子句中的旧语法替换为适当的连接子句:

MERGE INTO SPRENTHIERARCHIES 
USING ( SELECT c.PARENTCATEGORYID AS par,  
             e.rootcategoryId AS root 
        FROM  SPRENTCATEGORIES c
        LEFT JOIN SPRENTHIERARCHIES e 
        ON e.rootcategoryId = c.PARENTCATEGORYID 
      ) SPRENTCATEGORIES  
ON (SPRENTHIERARCHIES.rootcategoryId = SPRENTCATEGORIES.par) 
WHEN MATCHED THEN 
UPDATE SET SPRENTHIERARCHIES.rootcategoryId= SPRENTCATEGORIES.par  

但是,当您尝试更新连接列时,您遇到了一个更根本的问题;这将得到:

ORA-38104: Columns referenced in the ON Clause cannot be updated

正如 Gordon Linoff 建议的那样,您可以使用更新而不是合并。比如:

UPDATE SPRENTHIERARCHIES h
SET h.rootcategoryId = (
  SELECT c.PARENTCATEGORYID
  FROM SPRENTCATEGORIES c
  WHERE c.PARENTCATEGORYID = h.rootCategoryID
)
WHERE EXISTS (
  SELECT null
  FROM SPRENTCATEGORIES c
  WHERE c.PARENTCATEGORYID = h.rootCategoryID
)

where exists 子句是在没有匹配记录的情况下存在的——原始查询中的外连接暗示了这一点。但在这种形式中,更明显的是您要将rootcategoryId 更新为相同的值,因为您选择的 parentCategoryID 等于它。所以更新(或合并)似乎毫无意义。

【讨论】:

  • 我将在 SPRENTHIERARCHIES 中合并更多来自 SPRENTCATEGORIES 的列,这就是我使用合并的原因。是的,我正在使用 'c' 和 'e' 因为否则它会给我“无法更新 ON 子句中引用的列”错误。
  • @KavitaSalvi - 如果要更改 on 子句中的列,无论您使用什么名称或别名,都不能使用合并。更改它以使其更无效将无济于事。如果您实际上只是在更新其他列 - 因为无论如何更新目前都是毫无意义的 - 那么您就可以了。不过,您也可以使用更新语句更新多个列。
  • 好的 .. 我想要的只是我的 SPRENTHIERARCHIES 表更新,其中一些列来自 SPRENTCATEGORIES ,使用 c.PARENTCATEGORYID = h.rootCategoryID。我应该如何在 oracle 中执行此操作?
  • 只是不要SET SPRENTHIERARCHIES.rootcategoryId=...。如果您在 using 子句中获得其他新值,您可以使用这些值进行更新,但您无法更改 on 列。 (听起来你在复制数据,这有点奇怪)。如果这没有帮助,那么您应该提出一个新问题来解释您的要求并显示数据和预期结果。
  • 是的..复制列不是正确的方法。无论如何,我更改了代码。我可以通过不复制两列来解决问题。非常感谢你的帮助!干杯:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-04-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多