在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新手。
答案 0 :(得分:3)
两种解决方案:
使用别名,例如:
select
mpd.date
from
mydb_punchmedetails mpd
答案 1 :(得分: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小提琴显示了这些以及更多变体(有些起作用,有些却没有)
(感谢@WilliamRobertson指出了所讨论的问题。)
答案 2 :(得分:0)
您应该注意,通常不允许将其用作列名,因为它是用于数据类型和文字表达式(例如date '2018-08-03'
)的关键字。命名这样的列的唯一方法是通过在创建表时以及每次引用它时都使用完全相同的大写/小写字母将名称用双引号引起来来强制它。
很显然,这将永远导致额外的工作,并且会造成混乱,因为date
和timestamp
是两种不同的数据类型。
此操作失败:
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';