ORA-01843: 无效的月份

打印 上一主题 下一主题

主题 838|帖子 838|积分 2514

上个文章介绍了动态LINQ库
然后动态造了一个查询,示比方下:
  1. //ctx是EF的DbContext,字段Value是字符串类型
  2. 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无法辨认这样格式的时间值,那么它能辨认什么样的时间值呢,查下。
  1. SELECT * FROM v$nls_parameters;
复制代码
可以看到里面有很多环境参数,此中有NLS_TIMESTAMP_FORMAT和NLS_TIMESTAMP_TZ_FORMAT是我们需要注意的,它默认安装下是个很奇怪的时间格式,我们需要修改他们。
  1. alter session set NLS_TIMESTAMP_FORMAT="YYYY-MM-DD HH24:MI:SS.FF";
  2. alter session set NLS_TIMESTAMP_TZ_FORMAT="YYYY-MM-DD HH24:MI:SS.FF";
复制代码
这样就能辨认Value中的时间值了,不再报错。
不过需要注意的是这个仅仅是当前会话内有效,如果是EF中需要像下面的这样做。
  1. await ctx.OpenConnectionAsync();
  2. ctx.Database.ExecuteSqlRawAsync("alter session set NLS_TIMESTAMP_FORMAT="YYYY-MM-DD HH24:MI:SS.FF";");
  3. ctx.Database.ExecuteSqlRawAsync("alter session set NLS_TIMESTAMP_TZ_FORMAT="YYYY-MM-DD HH24:MI:SS.FF";");
  4. await ctx.Tables.Where("As(Value,"DateTime?")>@0",datetime).ToListAsync();
  5. await ctx.CloseConnectionAsync();//注意这句需要放到finally中
复制代码
你也可以修改oralce全局NLS_TIMESTAMP_FORMAT环境参数,那么代码就不需要这么改了。
如果是直接sql查询,可以修改sql语句的环境下,还可以用TO_TIMESTAMP方法利用指定的格式化字符串将Value字段转成TIMESTAMP,也能解决问题。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

缠丝猫

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表