审计实务工作中,经常会遇到被审计单位根据审计需求,将业务系统底层相关表导成文本文件提供给审计人员的现象,因审计关注的大多是业务系统核心表,数据量通常都比较大,所以导出的文本文件通常是大文本文件。由于审计人员更为熟练使用SQL Server数据库,为便于审计分析,审计人员通常需要将这些大文本文件导入SQL Server中,但在导入过程中,常常因数据类型不匹配、分隔符数量不匹配等原因而报错。而SQL Server的导入容错性差,报错后就终止导入,使得导入的数据无法使用,所以必须另辟蹊径来解决大文本文件导入SQL Server的报错问题。笔者结合审计工作实践,总结出两个办法以解决这一难题。 使用文本切割工具,将大文本文件切割成若干小文本文件,再用Access2003软件作为媒介进行导入 Access2003软件具有较好的容错功能,在出现源数据类型与目标数据类型不匹配而无法导入的情况时,仅对报错的字段信息不导入,其他数据都正常导入,而且在导入完成后,还生成一张报错信息表,提示错误类型、行数和字段,为修改或更新数据提供了极大便利。但Access2003数据库文件最大只有2GB,超过2GB就无法再导入,因此,超过2GB的大文本文件就无法直接导入Access2003数据库,而在审计实务工作中,被审计单位提供的文本文件大于2GB是正常情况。 文本切割工具(如TXT文件切割大师)按行切割文件,可以将大文本文件切割成若干个小文本文件,而且切割过程中不会造成数据损失。因此,可以使用文本切割工具将大文本切割成若干个2GB以内的小文本文件,再分批导入不同的Access2003数据库,解决大文本文件无法直接导入Access2003数据库的难题。由于SQL Server能够很好地兼容Access2003,所以将这些Access2003数据库文件依次导入SQL Server,再在SQL Server中将这些文件合并到一个数据表中,从而解决大文本文件导入SQL Server的难题。 利用字段分隔符特征编写函数,解决大文本文件导入难题 从Oracle、DB2等大型数据库导出的大文本文件,各个字段之间通常都以固定的分隔符来区分。因此,可以将大文本文件中的每行记录作为一个字段导入SQL Server数据库,再以分隔符为特征,编写一个函数取出各个字段内容。主要思路是以每行记录作为源字符串,以分隔符为查找目标,以分隔符的位置来确定取哪些内容为目标字段。下面以将大文本文件农户基本信息表导入SQL Server数据库为例进行阐述。 审计人员在保障性安居工程审计时,要求财政部门提供“惠民一卡通”系统的农户基本信息表,由于该系统的后台数据库是Oracle,涉及27类惠农补贴资金的管理,审计涉及的农村危房改造资金只是其中的一类。所以,财政部门根据审计工作需要提供了农村危房改造资金发放表和农户基本信息表,格式是文本文件,各字段之间用分隔符“”区分,其中农户基本信息表有两千余万行,数据量近3GB。 为开展数据分析工作,审计人员将这些数据导入SQL Server。由于财政部门提供的数据不规范,虽然字段之间用分隔符进行区分,但每条记录的第一个字符和最后一个字符都没有分隔符,只是两个字段之间有一个分隔符,所以SQL Server在导入文本文件时,无法利用分隔符来区分字段,需要将每行记录作为一个字段,导入后再编写脚本来区分出各个字段。 首先,定义一个函数,用于查找每条记录中的分隔符。从字符串中查找第几次出现某个字符串的函数,返回位置值。@SourceStr为源字符串,@SubStr为要查找的子字符串,@Position为要查找的子字符串第几次出现。 脚本如下: Create function FindPosition(@SourceStr varchar(8000),@SubStr varchar(10),@Position INT) Returns INT Begin Declare @i1 INT,@i2 INT Set @i1=1 Set @i2=charindex(@SubStr,@SourceStr) If @i1=@Position Return @i2 While @Position>@i1 Begin If charindex(@SubStr,@SourceStr,@i2+1)<>0 Set @i2=charindex(@SubStr,@SourceStr,@i2+1) Set @i2=0 Set @i1=@i1+1 Return@i2 其次,分析出前面15位定长为农户编码字段,第一个分隔符和第二个分隔符之间为姓名字段,第二个分隔符和第三个分隔符之间为银行账号字段,第三个分隔符和第四个分隔符之间为身份证号字段,第四个分隔符和第五个分隔符之间为家庭身份字段,第五个分隔符后面为家庭住址字段。 编写脚本从记录中筛查出各个字段,脚本如下: