我有一个表TABLE用来记录居民信息,结构如下:
Aid:居民街道号
id:居民身份证号——数据库中唯一
pid:父亲身份证号name:姓名
sex:性别
birth:出生日期
additional_info:附加信息现在已经有大量数据插入数据库,而手上有一个csv的数据文件,数据都是按照表结构排列。
我需要检查数据文件中的每条记录,去跟数据库中的记录对比看文件中各记录的每个字段有没有变化或被修改。比如csv文件中的一条记录是:
Aid:4
id:4030203
pid:34329223
name:alex
sex:male
birth:1980-8-4
additional_info:mmmmm我要查找数据库的TABLE,检查id,pid,name及sex字段的信息有没有被修改,如果任意两个字段信息都被修改则把该记录当做新记录插入数据库,如果只有一个字段信息不匹配则在数据库中修改该字段数据为csv文件中的值。我采取的方法是:1:先对csv文件按找sex排序
2:从csv中读取第一条记录,得到它的sex字段,假如为male
3:select * from TABLE where sex=male order by id;
4:根据从csv中读取的记录的id,在3步中返回的记录集中二分法查找
5:查到该id对应的记录后,分别判断其pid,name,sex等信息是否被修改,如果多于一个字段被修改,则把该记录插入数据库
6:如果没有查到该id对应的记录,就用TADOQuery.Locate(Aid,pid,name)定位。
7:如果Locate返回真,则说明只有id被修改,否则把该记录添加进数据库。我在SQL Server2000上做,BDS2006,11000条记录吧,做一次完整的audit需要35分钟左右,有没有更好的办法?欢迎高手指点,对于好算法可以再开帖加分。

解决方案 »

  1.   

    我的想法是这样的:(注以下方法是针对Oracle的,SQL Server的应该类似),假设原始表的名称为TB_Source,另外你的数据表中好像没有唯一键,这样不好确定记录的位置,可能是你没有说明。
    1、将CVS文件的数据导入到临时表中,用SQLLoder你的那些记录用不了10秒的!!!表的名称为TB_Target
    2、创建一个临时表,这个表中存储了所有的四个字段有任意一个不匹配的记录,同时在该表中增加一个标志字段X,用来标示该记录是否已经处理
    Create Table TB_Temp_A As
    ( Select 唯一键, ID, PID, SEX, NAME, 0 X From TB_Target
      Minus
      Select 唯一键, ID, PID, SEX, NAME, 0 X From TB_Source )
    3、以ID为基准,找出其他三个字段有不一致的数据
    Create Table TB_Temp B As
    ( Select 唯一键, ID From TB_Temp_A
      Minus
      Select 唯一键, ID From TB_Source )
    4、选择出来的数据就是ID不一致的数据了,然后将TB_Temp_A中的X更新为11,表示这些列有1个ID字段不一致
    Update TB_Temp_A
           Set X = 11
           Where( 唯一键 = ( Select 唯一键 from TB_Temp_B ) );
    5、选择出除了ID不一致以外,还有其他字段不一致的数据
    Update TB_Temp_A
           Set X = 21
           Where( X = 1 ) And
                ( 唯一键 = ( Select 唯一键 From 
                 ( Select 唯一键, PID, SEX, NAME From TB_Temp_B
                    Minus
                    Select 唯一键, PID, SEX, NAME From TB_Source ) ) );
    6、然后进行类似的循环,只不过在重复第三步的时候,在TB_Temp_A后加上条件X=0X字段值的定义为:0-未处理,11-ID字段不一致,21-除了ID不一致外还有其他字段不一致
                               12-PID字段不一致,22-除了PID不一致外还有其他字段不一致
                               13-Name字段不一致,23-除了Name不一致外还有其他字段不一致
                               14-Sex字段不一致,24-除了Sex不一致外还有其他字段不一致
                               
    7、处理完成后,你就可以按照你的要求将X<=14的数据进行更新,X>=21的数据进行插入
    以上的步骤写的比较简单,还需要你自己琢磨!!!按照我在Oracle上的经验,处以11000条数据在一个配置比较差的计算机上最多5分钟!!!
    另外,你的所有操作最好使用存储过程进行,这样不但效率高,而且存储过程的改动不影响到程序的结构!!!不需要重新编译程序(存储过程的参数变化除外)
      

  2.   

    在数据库中建一个临时表
    把csv数据放到数据库的临时表中,
    用sql 语句就可以实现了
      

  3.   

    这个唯一键的问题是这样的,源数据表是有一个主键,不能操作,是自动生成的。而我的csv文件里是没有这个键值的。导入数据库的时候我采用insert into的方式一条一条插入的,用bulk insert老是说什么datetime类型不匹配,烦都烦死了。
      

  4.   

    而且好像SQL Server里也没有Minus这个东东吧?
      

  5.   

    Create Table TB_Temp_A As
    ( Select 唯一键, ID, PID, SEX, NAME, 0 X From TB_Target
      Minus
      Select 唯一键, ID, PID, SEX, NAME, 0 X From TB_Source )
    ?????????这种创建表的方式看不懂,在SQL Server上提示说AS处有错误!