【问题标题】:Query fails when column is named 'DATE' (column name)当列名为“DATE”(列名)时查询失败
【发布时间】:2018-08-03 12:35:41
【问题描述】:

在 Oracle 10g 中,我有一个名为 MYDB_PUNCHTIMEDETAILS 的表,它有一个名为 DATE 的列,类型为 TIMESTAMP。每当我尝试执行以下语句时:

SELECT date FROM mydb_PUNCHTIMEDETAILS
WHERE  date like '19-01-15 11:56:39.000000000 AM'

它会产生以下错误:

行错误:51 列:9
ORA-00936: 缺少表达式

谁能建议如何获取数据或执行查询?我是 Oracle 的新手。

【问题讨论】:

  • 列的名称是"DATE"(大写)还是"date"(小写)?您应该知道这通常不允许作为列名,因为它是用于数据类型和文字表达式的关键字(例如date '2018-08-03')。像这样命名列的唯一方法是在创建表时以及每次引用它时将名称用双引号括起来来强制它。
  • like 对于时间戳比较应该是什么意思?你的意思是=
  • 小写“日期”
  • 非常感谢您给了我非常关键的时间。真的你们都那么可贵

标签: sql oracle oracle10g


【解决方案1】:

两种解决方案:

  • 使用命名标准 - 不要将表格列命名为“日期”、“数字”等 - 更具体一些,如“创建日期”、“交易日期”
  • 使用别名,如:

    select mpd.date from mydb_punchmedetails mpd

【讨论】:

  • 当我使用别名时,它的生成错误为:ORA-01747: invalid user.table.column, table.column, or column specification 01747. 00000 - "invalid user.table.column, table.列或列规范” *原因:*操作:第 51 行错误:第 11 列
  • 非常感谢您给了我非常关键的时间。真的你们都那么可贵
  • 好奇地看到你的 SQL 语句带有别名 - 可能跳过了一些东西。如果您愿意深入挖掘 - 发布它,我们会帮助您。
【解决方案2】:

将“日期”放在双引号中,

SELECT "date" FROM mydb_PUNCHTIMEDETAILS WHERE "date" like '19-01-15 11:56:39.000000000 AM'

另见the fiddle

更新

虽然 oracle 的隐式数据类型转换允许将时间戳与字符串进行比较,但 where 子句可能无法按预期工作,因为 LIKE 比较字符串:这取决于从时间戳到 varchar2 的隐式转换中使用的格式,这似乎有所不同在列值和文字之间(这可能是解析时优化的结果)。从概念上讲,在瞬间精度上的近似匹配可能根本不是意图。

要么选择精确比较(时间戳值的比较)

select "date" from test WHERE "date" = TIMESTAMP'19-01-15 11:56:39.000000000';

或构造一个匹配所需精度的like 参数:

-- ok (precision in comparison: minute)
select "date" from test WHERE "date" LIKE REPLACE(TIMESTAMP'19-01-15 11:56:39.000000000', '39.000000000', '%');

最简洁的方法是在数据类型之间显式转换并指定格式/精度:

select "date" from test WHERE TO_CHAR("date", 'YY-MM-DD HH24:MI:SS') LIKE TO_CHAR(TIMESTAMP'19-01-15 11:56:39.000000000', 'YY-MM-DD HH24:MI:SS');

更新后的 sql fiddle 显示了这些以及更多变体(有些有效,有些无效)

(感谢@WilliamRobertson 指出所讨论的问题。)

【讨论】:

  • 非常感谢您给了我非常关键的时间。真的你们都那么可贵
  • like 部分仍然是个问题,因为like 比较字符串,而"date" 是时间戳。
  • @WilliamRobertson 感谢您指出这一点。我已经相应地补充了答案。
【解决方案3】:

您应该知道这通常不允许作为列名,因为它是用于数据类型和文字表达式的关键字(例如date '2018-08-03')。像这样命名列的唯一方法是强制它,通过在创建表时将名称用双引号括起来,每次引用它时,使用完全相同的大写/小写字母。

显然,这将永远导致额外的工作,并且会造成混淆,因为 datetimestamp 是两种不同的数据类型。

这失败了:

create table mydb_punchtimedetails
( date timestamp );

ORA-00904: invalid identifier

您可以强制 Oracle 跳过其正常验证:

create table mydb_punchtimedetails
( "DATE" timestamp );

insert into mydb_punchtimedetails values (timestamp '2015-01-19 11:56:39');
insert into mydb_punchtimedetails values (timestamp '2018-08-03 14:10:00');

select d."DATE" from mydb_punchtimedetails d
where  d."DATE" = timestamp '2015-01-19 11:56:39';

【讨论】:

  • 非常感谢,你终于解决了我的问题,显然节省了我很多时间。非常感谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-11-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-02-06
  • 1970-01-01
相关资源
最近更新 更多