1、错误现象

  在向数据库查询一条数据的时候报如下错误:

    Value does not fall within the expected range.
at Oracle.ManagedDataAccess.Client.OracleParameter.set_Value(Object value)
at MyBatis.DataMapper.Data.DefaultPreparedCommand.ApplyParameterMap(IDbProvider dbProvider, IDbCommand command, RequestScope request, IStatement statement, Object parameterObject)
at MyBatis.DataMapper.Data.DefaultPreparedCommand.Create(RequestScope request, ISession session, IStatement statement, Object parameterObject)
at MyBatis.DataMapper.MappedStatements.MappedStatement.Execute[T](Object preEvent, Object postEvent, ISession session, Object parameterObject, Func` requestRunner)
at MyBatis.DataMapper.MappedStatements.MappedStatement.ExecuteInsert(ISession session, Object parameterObject)
at MyBatis.DataMapper.DataMapper.Insert(String statementId, Object parameterObject)

 错误信息也很简单。在向OracleParameter的属性Value赋值时报错。

2、找不出的错误原因

  源码如下:

  

 [Category("Data"), Description(""), DefaultValue((string) null)]
public override object Value
{
get =>
this.m_value;
set
{
if (((value != null) && (value != DBNull.Value)) && (this.m_enumType == PrmEnumType.NOTSET))
{
Type type = value.GetType();
if (((type == typeof(sbyte)) || (type == typeof(ushort))) || ((type == typeof(uint)) || (type == typeof(ulong))))
{
throw new ArgumentException();
}
object obj2 = OraDb_DbTypeTable.s_table[type];
if ((obj2 == null) && type.IsArray)
{
obj2 = OraDb_DbTypeTable.s_table[type.GetElementType()];
}
if (obj2 == null)
{
throw new ArgumentException();
}
this.m_oraDbType = (OracleDbType) obj2;
this.m_bSetDbType = false;
this.m_enumType = PrmEnumType.VALUE;
}
this.m_value = value;
}
}

  从源码可以看到,报错可能出现在两个地方:if (((type == typeof(sbyte)) || (type == typeof(ushort))) || ((type == typeof(uint)) || (type == typeof(ulong))))【更老的驱动版本bool类型也不支持】 和 if (obj2 == null)。出现这个错误说明无法将C#类型映射为Oracle类型。

  首先检查第一处可能,发现插入报错的类中使用的类型有DateTime,DateTime?,long,int,string。发现第一处不满足。

  检查第二次可能,第二处取类型是从 OraDb_DbTypeTable 获取到的。源码如下:

  

 internal static void InsertTableEntries()
{
s_table.Add(typeof(byte), OracleDbType.Byte);
s_table.Add(typeof(byte[]), OracleDbType.Raw);
s_table.Add(typeof(char), OracleDbType.Varchar2);
s_table.Add(typeof(char[]), OracleDbType.Varchar2);
s_table.Add(typeof(DateTime), OracleDbType.TimeStamp);
s_table.Add(typeof(short), OracleDbType.Int16);
s_table.Add(typeof(int), OracleDbType.Int32);
s_table.Add(typeof(long), OracleDbType.Int64);
s_table.Add(typeof(float), OracleDbType.Single);
s_table.Add(typeof(double), OracleDbType.Double);
s_table.Add(typeof(decimal), OracleDbType.Decimal);
s_table.Add(typeof(string), OracleDbType.Varchar2);
s_table.Add(typeof(TimeSpan), OracleDbType.IntervalDS);
s_table.Add(typeof(OracleBFile), OracleDbType.BFile);
s_table.Add(typeof(OracleBinary), OracleDbType.Raw);
s_table.Add(typeof(OracleBlob), OracleDbType.Blob);
s_table.Add(typeof(OracleClob), OracleDbType.Clob);
s_table.Add(typeof(OracleDate), OracleDbType.Date);
s_table.Add(typeof(OracleDecimal), OracleDbType.Decimal);
s_table.Add(typeof(OracleIntervalDS), OracleDbType.IntervalDS);
s_table.Add(typeof(OracleIntervalYM), OracleDbType.IntervalYM);
s_table.Add(typeof(OracleRefCursor), OracleDbType.RefCursor);
s_table.Add(typeof(OracleString), OracleDbType.Varchar2);
s_table.Add(typeof(OracleTimeStamp), OracleDbType.TimeStamp);
s_table.Add(typeof(OracleTimeStampLTZ), OracleDbType.TimeStampLTZ);
s_table.Add(typeof(OracleTimeStampTZ), OracleDbType.TimeStampTZ);
s_table.Add(typeof(OracleXmlType), OracleDbType.XmlType);
s_table.Add(typeof(bool), OracleDbType.Boolean);
s_table.Add(typeof(DateTimeOffset), OracleDbType.TimeStampTZ);
}

  发现里面没有DateTime?,难道是这个地方不行。那也不对啊,其它地方同样类型是可以保存到数据库的啊。继续找下去在 MyBatis.DataMapper.Data.DefaultPreparedCommand.ApplyParameterMap 找到了信息。源码如下:

  

 public virtual void SetParameter(IDataParameter dataParameter, object parameterValue, string dbType)
{
if (parameterValue != null)
{
dataParameter.Value = parameterValue;
}
else
{
dataParameter.Value = DBNull.Value;
}
}

  如果值为null,会自动赋值为 DBNull.Value 也就会不会报错。既然都不会出现问题,可问题又会出现在哪里呢?

3、柳暗花明

  在本地尝试各种方法后仍然不能重现,只能让领导将生产程序包拷贝一份下来进行尝试。

  包拿到之后,进行必要配置启动,出现了新的诡异问题 Redis报错 :No connection is available to service this operation。仔细检查Redis配置发现问题。抓下内存快照看看实际配置信息是什么:

  

  看到这个一脸懵逼,Password竟然是null,明明已经配置了啊。查看了加载配置的源码,发现根本不会解析Password配置,还有这种操作,这程序包是有多老。弄好了Redis,启动保存数据,果然不行。反编译生产源码,发现惊天一幕:

  

  Id的类型竟然ulong。我擦这是多久没有更新了。原因至此是找到了。

4、吐槽

  这个服务是公司内部自己用的,很古老了。以前都是手工拷贝程序包发布的。最近由于公司发生了些意外事情,原来服务器不能用,需要部署新的服务器上。由于古老,不知道老大当时拿了多么古老的程序包部署了。

 

Mybatis.NET Oracle 线上神奇问题:Value does not fall within the expected range.的更多相关文章

  1. Spring+SpringMVC+MyBatis+easyUI整合进阶篇(七)一次线上Mysql数据库崩溃事故的记录

    作者:13 GitHub:https://github.com/ZHENFENG13 版权声明:本文为原创文章,未经允许不得转载. 文章简介 工作这几年,技术栈在不断更新,项目管理心得也增加了不少,写 ...

  2. Spring+SpringMVC+MyBatis+easyUI整合进阶篇(八)线上Mysql数据库崩溃事故的原因和处理

    前文提要 承接前文<一次线上Mysql数据库崩溃事故的记录>,在文章中讲到了一次线上数据库崩溃的事件记录,建议两篇文章结合在一起看,不至于摸不着头脑. 由于时间原因,其中只讲了当时的一些经 ...

  3. DBAplus社群线上分享----Sharding-Sphere之Proxy初探

    功能 Cobar Mycat Heisenberg Shark TDDL Sharding-JDBC 是否开源 开源 开源 开源 开源 部分开源 开源 架构模型 Proxy架构 Proxy架构 Pro ...

  4. Springcloud及Git线上配置详解

    SpringCloud 这个阶段该如何学? 三层架构 + MVC 框架: Spring IOC AOP SpringBoot,新一代的JavaEE开发标准,自动装配 模块化~ all in one,代 ...

  5. 线上Linux服务器运维安全策略经验分享

    线上Linux服务器运维安全策略经验分享 https://mp.weixin.qq.com/s?__biz=MjM5NTU2MTQwNA==&mid=402022683&idx=1&a ...

  6. gradle测试与线上打包

    首先,第一反应理所当然的是profile : <?xml version="1.0" encoding="UTF-8"?> <beans xm ...

  7. 一次线上Mysql数据库崩溃事故的记录

    文章简介 工作这几年,技术栈在不断更新,项目管理心得也增加了不少,写代码的速度也在提升,感觉很欣慰,毕竟是在一直进步,但是过程中也有许许多多的曲折,也踩过了数不尽的坑坑洼洼,从一个连百度都不知道用的萌 ...

  8. 线上Mysql数据库崩溃事故的原因和处理

    前文提要 承接前文<一次线上Mysql数据库崩溃事故的记录>,在文章中讲到了一次线上数据库崩溃的事件记录,建议两篇文章结合在一起看,不至于摸不着头脑. 由于时间原因,其中只讲了当时的一些经 ...

  9. JVM 线上故障排查基本操作

    # 前言 对于后端程序员,特别是 Java 程序员来讲,排查线上问题是不可避免的.各种 CPU 飚高,内存溢出,频繁 GC 等等,这些都是令人头疼的问题.楼主同样也遇到过这些问题,那么,遇到这些问题该 ...

随机推荐

  1. typescript那些事儿

    本篇文章介绍typescript那些. ts-loader会调用typescript去编译.ts,typescript会读取tsconfig.json配置来决定如何编译. 在tsx文件中使用样式,需要 ...

  2. 使用sql语句创建和删除约束示例代码

    使用sql语句创建和删除约束  约束类型 主键约束(Primary Key constraint) --:要求主键列数据唯一,并且不允许为空.  唯一约束(Unique constraint) --: ...

  3. dockerui 安装

    meiya@meiya:~$ docker pull abh1nav/dockerui Using default tag: latest latest: Pulling from abh1nav/d ...

  4. mysql left join 右表数据不唯一的情况解决方法

    mysql left join 右表数据不唯一的情况解决方法 <pre>member 表id username1 fdipzone2 terry member_login_log 表id ...

  5. 1. Arduino对第三方开发板的支持

    Arduino对第三方开发板也有支持接口,需要手动添加,我们以STM32系列为例,说明添加过程. 目前st的官方提供的一系列板子都支持Arduino,可能是Arduino-IDE更新太慢,目前版本没有 ...

  6. 《ucore lab3》实验报告

    资源 ucore在线实验指导书 我的ucore实验代码 练习1:给未被映射的地址映射上物理页 题目 完成do_pgfault(mm/vmm.c)函数,给未被映射的地址映射上物理页.设置访问权限的时候需 ...

  7. 作为注册中心Eureka比Zookeeper好在哪里?

    作为注册中心Eureka比Zookeeper好在哪里?    著名的CAP理论指出,一个分布式系统不可能同时满足C(一致性),A(可用性)和P(分区容错性).由于分区容错性P在是分布式系统中必须要保证 ...

  8. SFTP客户端与服务端

    什么是 SFTP ? 在了解 SFTP 之前,我们先看看什么是 FTP . FTP( File Transfer Protocol )文件传输协议,是一种常用来在两终端系统之间传输文件的方法. SFT ...

  9. xsy 2414【CF587C】Duff in the Army

    Description [题目描述]: 最近有一场战争发生,Duff是战争里一名士兵,Malek是她的长官. 他们的国家——Andarz Gu有n个城市(编号为1到n),总共有n-1条道路,每条道路连 ...

  10. 剑指offer27:按字典序打印出该字符串中字符的所有排列

    1 题目描述 输入一个字符串,按字典序打印出该字符串中字符的所有排列.例如输入字符串abc,则打印出由字符a,b,c所能排列出来的所有字符串abc,acb,bac,bca,cab和cba. 输入描述: ...