隐藏在SQLServer 字段中的超诡异字符解决过程

所属分类: 数据库 / MsSql 阅读数: 886
收藏 0 赞 0 分享

文章作者:jhkdiy
发表日期:2009-10-11
程序架构:B/S
开发环境:Windows XP + IIS6 + VS2003
数 据 库:SQL Server 2000
部分功能:从 SQL Server 中导出数据到 Access。
这套系统做了大半年,这个导入导出还是问题不断,我负责的这块导入导出就是夹在网
络版和单机版系统之间,只要任何一边对数据库做了改动这个导入导出就会失败。哎,烦心
的事不止这些,最近又遇到了一个非常奇怪的问题。
由于之前的导入导出使用SQL Server 支持的OpenDataSource()函数来做,而当遇到
64位系统时就会遇到不支持Microsoft.Jet.OLEDB.4.0 ,所以重新编码,技术步骤是先从SQL Server 读数据到DataTable,然后遍历这个DataTable,对每一行,将里面的数据重新组合成一条Insert 语句,然后打开Access文件链接,执行刚才生成的Insert语句,将数据插入到Access中。
我最终提交给Access执行的语句是根据SQL Server中的数据拼出来,比如SQL Server :select a, b, c from tblTemp
提交给Access执行的语句就是:

复制代码 代码如下:

Str1 = “Insert into”
Str2 = “tblTemp(a,b,c)values(”
strResult = str1 & str2 & “‘aa', 2, ‘cc' ” & “)”

这回的重大问题是在SQL Server 表的b字段中有特殊字符,此字符使我的程序无法拼出完整的字符串,拼出来的字符串strResult 有时不带最后的“)”,但奇怪的是,这个表总共有4万多条记录,只是组合个别记录才会出现这个现象。但是提交给Access执行肯定不通过,提示SQL语法错误。
我于是查询数据库的这条记录,用查询分析器查询没发现任何的特殊字符,问了同事后才知道,他说之前有过部分表中的某些字符保存了客户输入的回车换行符,我顿时大悟,对呀,回车换行符是看不见的啊,于是,想使用下面的语句查询字段中是否有回车换行符:
复制代码 代码如下:

select charindex(char(10), demc) from tblgc_jc_de where xh = 15641
select charindex(char(13), demc) from tblgc_jc_de where xh = 15641
select charindex(char(10) + char(13), demc) from tblgc_jc_de where xh = 15641
select charindex(char(13) + char(10), demc) from tblgc_jc_de where xh = 15641

但奇怪的是,返回都是0,也就是找不到。这就郁闷了,字段中到底存储了什么字符啊?,另一个同事教了一招,直接在企业管理器中返回该表的所有行记录,然后全选查看该字段,发现确实是多出一个字符:
查到有个看不见的字符
不是回车换行符会是什么字符呢?在百思不解之际,突然想起,不如看看这个表物理数据,一定能查出存储在该字段的是什么字符。但是该表有44022条记录,查某一条记录的物理数据就是大海捞针,怎么办???
我只想查询这条记录的物理数据要怎么做?能不能把这条数据放到另一个表中,这个表只有这一条记录,这不就可以查看了吗。哦,这个简单,其实我同时建立了一个临时的数据库,这个数据库只有一张表,这张表只有一条记录,就是包含上面那个有问题的记录,使用的SQL语句如下:
-- TYZW 是正式库
use TYZW
-- 创建一个临时数据库,然后将有问题的那条
-- 记录插入临时库。
create database tmpTYZW
go
select * into tmpTYZW..tblgc_jc_de from tblgc_jc_de where xh = 15641
go
现在是时候查看一下这条记录的物理数据了,首先要在sysindexes系统表中查找出该表在物理文件中的位置,然后我们可以通过 dbcc page 命令查看物理数据:
查看表记录在文件中的位置
接着使用dbcc page命令查看物理数据:
查看物理数据


现在是时候看看这条记录的物理数据了:

物理数据

 


天啊,竟然是0,真不晓得是怎么存进去的。问题终于知道在那了,但是要如何解决呢?最简单的方法就是将这个0替换掉,于是使用下列语句测试:

select replace(demc, char(0), '') as demc from tblgc_jc_de

 

但是不行,原因是replace函数找不到0这个字符,因为它查找是按两个字节来找的,所以直接在SQL Server上找也找不到这个字符,替换也替换不了。但是,我又想了一下,能不能使用二进制来查找和替换?看了一下资料,使用下面的SQL语句能找出0在该字段的位置:

二进制方式查询字符位置查是能查出来了,但是我发现replace函数还是不能用,除非是替换4位,也就是0x0038。

最后实在无奈,只能直接把有这个特殊字符的地段截掉一个文字,也就是连那个38也不要了:

select

case  when charindex(convert(varbinary(1),0x00),convert(varbinary(200),demc)) > 0

         then substring(demc,1,len(demc)-1)

         else demc

         end as DEMC

from tblgc_jc_de

 

这就是我现在用的最终解决方案,因为我查询过,4万多条记录中只有8条有这个0在字段里面。所以就算截掉一个文字并影响程序的功能和显示。

虽然我现在写出来很多步骤看似走的很顺,其实这个问题我用了几天时间了,主要是找问题所在耗费了不少时间。现在给出此文希望广大朋友在找这些问题时多个方向,因为存储在字段中的特殊字符不一定就是常规的回车换行符,也有可能是其它字符,在此大家互相学习提高吧。

更多精彩内容其他人还在看

浅析SQL Server 聚焦索引对非聚集索引的影响

本篇文章对SQL Server的聚焦索引和非聚集索引进行简单分析,从而总结出聚焦索引对非聚集索引的影响。有兴趣的朋友可以看下
收藏 0 赞 0 分享

浅析SQL Server的聚焦使用索引和查询执行计划

本文通过介绍默认使用索引、强制使用聚集索引、强制使用非聚集索引让我们知道对于检索所有列结果集使用主键的聚集索引是最佳选择。有兴趣的朋友可以看下
收藏 0 赞 0 分享

详解SQL Server中的数据类型

本文主要讲解了SQL中的数据类型以及几个需要注意的地方,简短的内容,深入的理解。有兴趣的朋友可以看下
收藏 0 赞 0 分享

浅析SQL Server的分页方式 ISNULL与COALESCE性能比较

本文上述重点讲述了SQL Server的分页方式,COALESCE和ISNULL函数区别之处,简短的内容,深入的理解。有兴趣的朋友可以看下
收藏 0 赞 0 分享

浅述SQL Server的聚焦强制索引查询条件和Columnstore Index

本文主要讲了强制使用索引条件来进行查询,当对于使用默认创建索引进行查询计划时觉得不是最优解,可以尝试使用强制索引来进行对比找出更好得解决方案。简短的内容,深入的理解.有兴趣的朋友可以看下
收藏 0 赞 0 分享

详解SQL Server的聚焦过滤索引

本文主要讲解了通过过滤索引来提高查询性能,同时也给出了其不同的场景以及其使用优点和明显的缺点。简短的内容,深入的理解,有兴趣的朋友可以看下
收藏 0 赞 0 分享

解析SQL Server聚焦移除(Bookmark Lookup、RID Lookup、Key Lookup)

本文主要讲解索引性能优化,着重对Bookmark Lookup、RID Lookup、Key Lookup三者进行移除的实现进行解析,以此来提高查询性能。希望对大家有所帮助
收藏 0 赞 0 分享

SqlServer 注释符 单行注释与多行注释

这篇文章主要介绍了SqlServer 注释符 单行注释与多行注释,需要的朋友可以参考下
收藏 0 赞 0 分享

SQL设置SQL Server最大连接数及查询语句

今天遇到了关于Sql Server最大连接数(Max Pool Size)的问题,后来通过查找一些资料解决了,所以想着总结下关于SQL Server最大连接数的内容,所以这篇文章主要介绍了SQL设置SQL Server最大连接数与查询语句,有需要的朋友们可以参考借鉴。
收藏 0 赞 0 分享

浅谈SQL Server交叉联接 内部联接

本文主要讲了SQL Server的交叉联接和内部联接,同时也给出了使用需要注意的地方。有需要的朋友可以看下
收藏 0 赞 0 分享
查看更多