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

文章作者: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在字段里面。所以就算截掉一个文字并影响程序的功能和显示。

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

(0)

相关推荐

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

    文章作者:jhkdiy 发表日期:2009-10-11 程序架构:B/S 开发环境:Windows XP + IIS6 + VS2003 数 据 库:SQL Server 2000 部分功能:从 SQL Server 中导出数据到 Access. 这套系统做了大半年,这个导入导出还是问题不断,我负责的这块导入导出就是夹在网 络版和单机版系统之间,只要任何一边对数据库做了改动这个导入导出就会失败.哎,烦心 的事不止这些,最近又遇到了一个非常奇怪的问题. 由于之前的导入导出使用SQL Server

  • 记一次Django响应超慢的解决过程

    在本地windows机器开发的Django项目运行正常,放到服务器上后响应超慢,花了一整个工作日没找到原因(非常绝望),又花了一整个周末才找到原因和临时解决办法,如果你的项目超慢可以参考一下解决思路. 排查过程: 1.怀疑是Python环境问题,到服务器上各种虚拟环境版本进行尝试,无果. 2.因为用了mysql数据库,开始用pymysql包连接改动了一些参数,担心是驱动问题导致数据库查的慢,更换mysqlclient包后,响应依旧慢. 3.担心是有什么报错导致慢,于是艰难地开启了debug模式(

  • PostgreSQL去掉表中所有不可见字符的操作

    问题描述 数据库中的某些数据中包含了某些不可见字符.ASCII码中的0-31,127属于控制字符,不可见. 这些不可见字符往往是不需要的,我们要想办法删除它. 解决办法 写一函数,将所有字段中的不可见字符替换为空格. 测试流程 环境准备 建表,并插入带不可见字符的记录.注:下列数据中的不可见字符在粘贴过来的时候自动去掉了,请按ALT+数字键加入. CREATE TABLE public.test_table ( xm character varying(50), pinyin character

  • PHP中的超全局变量

    PHP中的超全局变量 从PHP 4.2.0 开始,register_globals 的默认值为 off,这样一来,以前的很多可以直接使用的变量,如 $PHP_SELF 或者你设定的SESSION变量都不能用 "$变量名"的形式访问了,这可能会给你带来很多不变,但却有助于安全性的提高.访问这些变量,你需要使用PHP 超全局变量,如下: $_SERVER 变量由 Web 服务器设定或者直接与当前脚本的执行环境相关联.类似于旧数组 $HTTP_SERVER_VARS 数组.以前的$PHP_S

  • MySQL将一个字段中以逗号分隔的取出来形成新的字段实现

    1例如:要把如图1的字段拆分图2 select account_id, substring_index(substring_index(a.related_shop_ids,',' ,b.help_topic_id+1),',',-1) shopid from sales_hang_account a join mysql.help_topic b on b.help_topic_id < (length(a.related_shop_ids) - length(replace(a.relate

  • jsp隐藏关键敏感字段信息只显示前后字段的示例

    今天写jsp页面,要求对字段中间部分隐藏,只显示前几位和后几位.搜了一下发现网上大都是隐藏前面指定字段,或者是利用正则表达式隐藏手机号或是身份证.这样的话必须预先知道字段长度,而我不想知道长度只显示前3位和后4位. 没办法,谁让我需要隐藏的字段长度未定呢. 解决方案:1.如果知道字段长度的话可以用正则表达式或是jsp标签库里的fn函数 正则表达式 phone.replaceAll("(\\d{3})\\d{4}(\\d{4})","$1****$2"); 152**

  • mysql中如何判断当前是字符 mysql判断字段中有无汉字

    使用length与char_length两个函数 length:是计算字段的长度一个汉字是算三个字符,一个数字或字母算一个字符 char_length:不管汉字还是数字或者是字母都算是一个字符 对同一字段分别使用length.char_length计算长度,并进行比较长度相同则字段中无汉字,不相同则肯定有汉字 复制代码 代码如下: SELECT   * FROM  t_ad t WHERE t.`userid` = 974   AND LENGTH(    REPLACE(REPLACE(t.`

  • MySQL批量去掉某个字段中的空格

    Mysql有什么办法批量去掉某个字段字符中的空格?不仅是字符串前后的空格,还包含字符串中间的空格,答案是 replace,使用mysql自带的 replace 函数,另外还有个 trim 函数. (1)mysql replace 函数 语法:replace(object,search,replace) 意思:把object中出现search的全部替换为replace 案例:清除news表中content字段中的空格 update `news` set `content`=replace(`con

  • 在MySQL字段中使用逗号分隔符的方法分享

    被分割的字段一定是有限而且数量较少的,我们不可能在一个字符串中存储无限多个字符 这个字段所属的表与这个字段关联的表,一定是一对多的关系 比如下面这个表结构所代表的content与tag这两个对象 复制代码 代码如下: mysql> SELECT * FROM content; +----+------+| id | tags | +----+------+| 1 | 1,2 | | 2 | 2,3 | +----+------+ 2 rows in set (0.01 sec) mysql>

  • 批量替换 MySQL 指定字段中的字符串

    批量替换的具体语法是: 复制代码 代码如下: UPDATE 表名 SET 指定字段 = replace(指定字段, '要替换的字符串', '想要的字符串') WHERE 条件; 如果你想把 article 表中 ID 小于5000的记录,content 字段中"解决"替换成"解放",那么语法就是: 复制代码 代码如下: UPDATE article SET content = replace(content, '解决', '解放') WHERE ID<5000

随机推荐