锑砖 发表于 2025-6-10 19:33:29

ORA-01843: 无效的月份

上个文章介绍了动态LINQ库。
然后动态造了一个查询,示例如下:
//ctx是EF的DbContext,字段Value是字符串类型
await ctx.Tables.Where("As(Value,\"DateTime?\")>@0",datetime).ToListAsync();上面的查询条件在Oracle下大概是这样:CAST("Value" AS TIMESTAMP(7))>:datetime
然后报错ORA-01843: 无效的月份,原因是Value字段的值存的是这样的格式:"yyyy-MM-dd hh:mm:ss",oracle无法识别这样格式的时间值,那么它能识别什么样的时间值呢,查下。
SELECT * FROM v$nls_parameters;可以看到里面有很多环境参数,其中有NLS_TIMESTAMP_FORMAT和NLS_TIMESTAMP_TZ_FORMAT是我们需要注意的,它默认安装下是个很奇怪的时间格式,我们需要修改他们。
alter session set NLS_TIMESTAMP_FORMAT="YYYY-MM-DD HH24:MI:SS.FF";
alter session set NLS_TIMESTAMP_TZ_FORMAT="YYYY-MM-DD HH24:MI:SS.FF";这样就能识别Value中的时间值了,不再报错。
不过需要注意的是这个仅仅是当前会话内有效,如果是EF中需要像下面的这样做。
await ctx.OpenConnectionAsync();
ctx.Database.ExecuteSqlRawAsync("alter session set NLS_TIMESTAMP_FORMAT=\"YYYY-MM-DD HH24:MI:SS.FF\";");
ctx.Database.ExecuteSqlRawAsync("alter session set NLS_TIMESTAMP_TZ_FORMAT=\"YYYY-MM-DD HH24:MI:SS.FF\";");
await ctx.Tables.Where("As(Value,\"DateTime?\")>@0",datetime).ToListAsync();
await ctx.CloseConnectionAsync();//注意这句需要放到finally中你也可以修改oralce全局NLS_TIMESTAMP_FORMAT环境参数,那么代码就不需要这么改了。
如果是直接sql查询,可以修改sql语句的情况下,还可以用TO_TIMESTAMP方法使用指定的格式化字符串将Value字段转成TIMESTAMP,也能解决问题。

来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

圄旧剖 发表于 2026-1-6 04:54:31

用心讨论,共获提升!

栓州 发表于 2026-1-7 23:01:07

过来提前占个楼

拓炊羡 发表于 2026-1-14 03:25:41

感谢分享,学习下。

忆雏闲 发表于 2026-1-14 22:20:31

用心讨论,共获提升!

告陕无 发表于 2026-1-21 03:38:51

谢谢分享,试用一下

坪钗 发表于 2026-1-22 11:26:31

不错,里面软件多更新就更好了

泡市 发表于 2026-1-23 09:59:00

过来提前占个楼

骆贵 发表于 2026-1-25 12:05:24

感谢发布原创作品,程序园因你更精彩

荪俗 发表于 2026-1-28 03:53:05

热心回复!

氛疵 发表于 2026-1-29 16:27:03

分享、互助 让互联网精神温暖你我

步雪卉 发表于 2026-1-30 02:03:31

前排留名,哈哈哈

届表 发表于 2026-2-1 03:40:58

用心讨论,共获提升!

蔬陶 发表于 2026-2-3 07:59:58

热心回复!

刘凤 发表于 2026-2-4 10:08:45

不错,里面软件多更新就更好了

骆贵 发表于 2026-2-5 02:38:55

谢谢楼主提供!

姚望舒 发表于 2026-2-6 04:11:29

鼓励转贴优秀软件安全工具和文档!

赫连如冰 发表于 2026-2-7 23:54:07

感谢发布原创作品,程序园因你更精彩

玻倌瞽 发表于 2026-2-8 20:23:08

感谢发布原创作品,程序园因你更精彩

扎先 发表于 2026-2-9 03:33:12

谢谢楼主提供!
页: [1] 2
查看完整版本: ORA-01843: 无效的月份