最近需要维护一个差不多十多年前开发的ASP.Net程序,遇到了各种奇奇怪怪的问题,把其中比较难查明的问题记录如下:

问题一:

同样的SQL查询在不同服务器上查询结果不同。在QA环境下,结果完全正常,而在本地,部分字段值为DBNull。

这是一个很诡异的问题,当时唯一发现的规律是,出现DBNull值的字段为Clob类型。ASP.Net连接数据库的方式为OleDb,链接字符串中“Provider=OraOLEDB.Oracle.1”。

首先换为OracleClient,查询结果正常,问题似乎出在OleDb上。网上也有关于Clob类型的一些资料,但是为什么QA服务器上又没问题呢。

带着这个问题,我做了一个能通过.Net里不同Client执行Sql查询的小工具,放到QA服务器上运行,结果确实是正常的。

QA服务器的环境为32位,Oracle客户端主版本为10,我自己的电脑环境为32位,Oracle客户端主版本为11。

接着我在几个服务器上尝试,结果都正常。我开始怀疑自己电脑上的Oracle客户端安装不正常,于是卸载重装,结果依旧。

对照注册表

HKEY_LOCAL_MACHINE\SOFTWARE\Oracle\KEY_OraClient11g_home1\OLEDB 

HKEY_LOCAL_MACHINE\SOFTWARE\Oracle\ODP.NET\2.112.1.0

发现键值完全一致。这时我开始怀疑是32位与64位的差异。因为之前测试过的服务器都是64位的,只有QA环境是32位,而QA环境又是10版本的客户端。

最后找到了一台32位环境的服务器,客户端版本为11,问题重现。

因此推测,OleDb查询Clob字段的问题是在32位系统上运行32位客户端造成的,64位系统上的64位客户端似乎都不存在这个问题。至于64位系统上的32位客户端是否存在这个问题,因为时间关系就不亲自验证了。而该问题似乎与服务器无关,因为在32位和64位服务器上都会重现这个问题。

因此,这个问题可以重新描述:使用32位系统下的32位Oracle Provider for OLE DB查询含有Clob字段类型的数据时可能得到假空值的结果。

解决方式有两种,使用OracleClient类访问数据库或者使用Provider=msdaora;的方式访问数据库,这其实是一样的方法,都是使用Microsoft OLE DB Provider for Oracle;

另一种解决方式就是将服务器升级为64位环境,并尽可能安装64位客户端。目前来看应该是Oracle Provider for OLE DB在处理字符编码时的Bug。

[2016/5/5问题一补充:因为系统环境不同,这个问题可能不一定会重现,目前已知会影响重现的因素是注册表 HKEY_LOCAL_MACHINE\SOFTWARE\Oracle\KEY_OraClient11g_home1下NLS_LANG的值。当系统区域和语言选项中,格式选择为中国,则该值默认为SIMPLIFIED CHINESE_CHINA.XXXX,这种情况下查询结果正常。若系统区域和语言选项中,格式为美国,则NLS_LANG的值默认为AMERICAN_AMERICA.WE8MSWIN1252,这种情况才会出现这个问题。目前没有发现这个问题跟服务器端的NLS_LANG值有关。]

问题二:

有西班牙语特殊字符的查询结果在不同服务器上查询结果显示不同,本地执行有乱码,QA服务器正常。

这个问题也纠结了挺久,在各种尝试无果后想到了一个控制面板的配置项:在"Region and Language"配置项的管理员选项卡中有一个"Language for non-Unicode programs"选项。之前为了运行某些没有使用Unicode编码的国产软件时将这个配置项改为了中文,我的系统本来是英文版的。于是将这个选项改回英文,问题解决。

因此,这个问题可以重新描述:使用Oracle Provider for OLE DB查询含有非Unicode编码字段内容时,若系统的非Unicode语言选项不正确,会导致查询结果编码不正确的问题。

Oracle诡异结果调查备忘 - A investigation memo of weird Oracle database search results的更多相关文章

  1. ORACLE 连接SQLSERVER 数据库备忘

    最近工作需要,要从SQL SERVER数据库中同步提取数据. 这里采用了  Oracle Gateway 来连接,折腾了半天,终于搞定,记录下已备下次使用. 基本资料网上都可以搜很多,官网配置说明在这 ...

  2. Oracle用法、函数备忘记录

    Listagg select * from emp select LISTAGG(ename,'-') within group (order by deptno desc) from emp; 可以 ...

  3. 项目中oracle存储过程记录——经常使用语法备忘

    项目中oracle存储过程记录--经常使用语法备忘 项目中须要写一个oracle存储过程,需求是收集一个复杂查询的内容(涉及到多张表),然后把符合条件的记录插入到目标表中.当中原表之中的一个的日期字段 ...

  4. Oracle使用备忘

    初学Oracle,很多语句记不住,写在这里备忘. 1.查看某表空间的数据文件 select file_name 文件名, tablespace_name 表空间名, bytes 已使用大小M, max ...

  5. oracle下 启动subversion命令 及 oracle相关服务启动备忘

    linux shell下  svnserve - d -r + 目录   例如:svnserve -d -r /svn 启动 svn服务. 访问svn://192.168.0.120/kjcg 测试. ...

  6. centos 6.4 mysql rpm 离线安装【备忘】

    离线状态下使用rpm的安装包进行mysql的安装,仅作备忘 准备工作: 官网下载mysql离线rpm安装包(这里就不演示了,拿现成的做演示) =================更新线 2018-01- ...

  7. JVM内存知识备忘

    又是一篇备忘... 主要记录一些知识,进行一些资源的汇总. 先来群里liufor大大提供的两张图,清晰易懂: Dockerized Java https://www.youtube.com/watch ...

  8. 工作T-SQL备忘

    作为一个"浸淫" Oracle 数据库很久的人来说, 突然转入 T-SQL, 也就是 MSSQL , 工作中经常用的查询和 MSMS 使用备忘如下 : --1. 切换对应的库连接 ...

  9. Annotation 使用备忘

    title: Annotation 使用备忘 date: 2016-11-16 23:16:43 tags: [Annotation] categories: [Programming,Java] - ...

随机推荐

  1. 给linux 授权一个可以远程登录的账户

    创建用户:grant all on *.* to '; 授权:flush privileges;

  2. HDU-2825 Wireless Password(AC自动机+状压DP)

    题目大意:给一系列字符串,用小写字母构造出长度为n的至少包含k个字符串的字符串,求能构造出的个数. 题目分析:在AC自动机上走n步,至少经过k个单词节点,求有多少种走法. 代码如下: # includ ...

  3. aop配置

    前置通知 后置通知 环绕通知 异常通知 定义切面 aop-config 切入点 切面 通知 spring jdbc

  4. 【P1379】天才的约数和

    来自GDOI2007,原题已不可考-- 又自己做出来了好开心,找特殊性是个关键的切入点 原题: 这天周航遇到了靳泽旭. 周航:"我是天才!" 靳泽旭:"你为什么是天才?& ...

  5. Java BigDecimal 加减乘除运算

    加法:add 减法:subtract 乘法:multiply 除法:divide BigDecimal bignum1 = new BigDecimal("10"); BigDec ...

  6. chart.js插件生成折线图时数据普遍较大时Y轴数据不从0开始的解决办法[bubuko.com]

    chart.js插件生成折线图时数据普遍较大时Y轴数据不从0开始的解决办法,原文:http://bubuko.com/infodetail-328671.html 默认情况下如下图 Y轴并不是从0开始 ...

  7. ruby HTTPS请求

    require 'uri'require 'net/http'require 'net/https' @toSend = { "date" => "2012-07- ...

  8. 条款19:设计class犹如设计type

    1,新的type对象应该如何被创建和销毁? 这会影响class的构造函数ctor和析构函数dtor,以及内存分配函数和释放函数   //operator new //operator new[] // ...

  9. 【学】React的学习之旅3 - 添加事件(onClick)

    button除了用<input type="button">之外,还可以直接用<button></button>来创建,而2个标签的中间的内容就 ...

  10. php生成curl命令行

    e.g. curl “http://localhost/other/serverInfo.php?dd=ddd” -H “Host:localhost” -H “Connection:keep-ali ...