【问题标题】:Oracle - Invalid Identifier for column nameOracle - 列名的标识符无效
【发布时间】:2019-11-26 00:18:21
【问题描述】:

我在NUMBER 字段中遇到了一个有趣的情况。

这是一个简化的例子。

当我选择一个恰好有 29 个字符长的特定字段时,它工作得很好。

select FIELD_NAME_THAT_IS_29_CHAR_XX
from table;

在使用此查询的报告中,该查询不返回标题(这是一个 eText 类型的 XML 发布者报告)。但是,当我使用 UNION 运行查询并选择标题名称时,我得到一个无效标识符错误。

SELECT "FIELD_NAME_THAT_IS_29_CHAR_XX" FROM dual
UNION
SELECT FIELD_NAME_THAT_IS_29_CHAR_XX FROM table1;

返回:

ORA-00904: "LINE_RECEIPT_AMNT_AT_COST_USD": invalid identifier

Oracle DB 中字段名的最大长度为 30 个字符。我是否达到了这个限制?我认为不是这样,例如:

SELECT "FIELD_NAME_THAT_IS_29_CHAR_XXxxxxx" FROM dual;

..给出:

ORA-00972: identifier is too long

UNION 有什么问题?

单引号也不起作用。这是一个NUMBER 字段。

SELECT 'FIELD_NAME_THAT_IS_29_CHAR_XX' FROM dual
UNION
SELECT FIELD_NAME_THAT_IS_29_CHAR_XX FROM table1;

..给出:

ORA-01790: expression must have same datatype as corresponding expression

【问题讨论】:

  • 如果去掉双引号会怎样?也许甲骨文以某种方式计算它们。
  • SELECT "FIELD_NAME_THAT_IS_29_CHAR_XX" FROM dual 可能不起作用,因为 dual 没有该字段。
  • 它给出了同样的错误,带或不带引号。
  • @Adder - dual 不能那样工作。
  • dual 就是这样工作的。它给出了错误invalid identifier

标签: sql oracle


【解决方案1】:

问题在于双引号

Oracle SQL 允许我们忽略数据库对象名称的大小写,只要我们使用全部大写的名称创建它们,或者不使用双引号。如果我们在脚本中使用混合大小写或小写,并将标识符包裹在双引号中,我们将被谴责使用双引号,并且在引用对象或其属性时使用精确大小写:

改为使用单引号,它基本上可以工作,并且会给你想要的结果

http://sqlfiddle.com/#!4/dce84/4

【讨论】:

  • SELECT "FIELD_NAME_THAT_IS_29_CHAR_XXxxxxx" FROM dual; 我知道这行得通。另一件事是错误明确指出数据类型不同ORA-01790: expression must have same datatype as corresponding expression一个是字符串,列是数字类型
  • 所以你需要这样做而不是SELECT 'FIELD_NAME_THAT_IS_29_CHAR_XX' FROM dual UNION SELECT FIELD_NAME_THAT_IS_29_CHAR_XX FROM table1; 可能SELECT 20 FROM dual UNION SELECT FIELD_NAME_THAT_IS_29_CHAR_XX FROM table1; 才能使其工作
【解决方案2】:

@Standin 回答引导我找到解决方案。

因为选中的字段是一个数字,所以只需要将 is 转换成 char - 加上单引号即可。

SELECT 'FIELD_NAME_THAT_IS_29_CHAR_XX' FROM dual
UNION
SELECT to_char(FIELD_NAME_THAT_IS_29_CHAR_XX) FROM table1;

【讨论】:

  • 问题中报的SQL错误是因为双引号是用来包围标识符的,而不是字符串字面量。 Oracle 正在表DUAL 中查找该名称的列,而该列名称在DUAL 中不存在。现在将它们更改为单引号使其成为字符串文字,并解决了该问题。 (我们会看到只运行第一个 SELECT,没有 UNION。)其次,我们遇到了 UNION 集合操作的限制,列数必须完全匹配,返回列的数据类型必须兼容。跨度>
  • 如果您知道,这两个查询将永远不会返回相交的行(这是您的情况),您应该始终使用 UNION ALL 而不是*排序两者的 UNION数据集并删除重复项。
猜你喜欢
  • 2016-03-31
  • 1970-01-01
  • 2021-03-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多