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,也能解决问题。