场景:
远程数据库A是mySql数据库,tb_a_20120806是库A的表,库A按每天的年月日会自动生成新表,字段一样内容不同,而且数据量巨大。
本地数据库B是sqlServer2008,tb_Alla是库B的表,只有一个,字段结构与tb_a_20120806相同。
要求:
1.利用C#程序,开线程读取库A的表tb_a_20120806,读取结果插入tb_Alla表。
2.线程需重复读取一定量的数据,尽量保持两边数据同步。过0点后自动读第二天的表。
3.程序界面显示每次的读取开始时间和结束时间,并显示是否成功,读取插入多少条数据。2,3条好说,只要程序实现读取插入,及比较好计算出时间,返回是否成功插入等信息。问题是第1条要求,C#程序如何实现。 用SQlserver的事物建立DBLink可以定时同步,但是库A的表是动态生成的,而且更重要的是,不能使用sql的操作界面看事物信息,应为以后可能还要扩展功能。要用C#程序实现并反映在界面上,以供以后做其他功能。请问,C#代码如何实现这种不同数据库数据的导入?

解决方案 »

  1.   

    突然想到,把从库A读出的数据放进Table,然后再把Table整个插入库B。这样效率怎么样?
      

  2.   

    效率不高!!!!
    你的应用和我们的场景极其相似。
    你用DataReader+object()+cmd.ExecuteNonQuery会好点
    最好的方式是在Mysql里写自定义函数
      

  3.   

    同步一定要设置一个ID用来计数,SQL Server那边最好不要有约束条件
      

  4.   

    开个Times.Timer
            Dim _Timer_GetLog As New Timers.Timer()
            AddHandler _Timer_Sync_Data.Elapsed, AddressOf Sync_Data
            _Timer_Sync_Data.Interval = 300000
            _Timer_Sync_Data.Start()
    sub Sync_Data()
    End Sub
    把你做的同步函数放Sync_Data在里头
        
      

  5.   


    非常感谢。
    能用C#代码大概写一下么?有点晕。
    SQL Server那边基本没有约束条件。线程什么的我已经设计好了,就是中间转存数据的时候不知道怎么写。
      

  6.   


    MysqlRule = new MysqlRule(ip, Port, DBName, Uid, Pwd);
    MySqlDataReader MySqlDataReader = MysqlRule.getMysqlread("select * from t_A_20120723");
    if (MySqlDataReader.FieldCount > 0)
    {
     //当记录存在时,将记录插入到本地sqlserver数据库。
    }以上的代码片段是放在线程里执行的,if语句里就不知道怎么写了。我用的是MySql.Data.dll连接Mysql。Mysql服务器是别人的服务器,无法写函数什么的你,只有查询权限。
      

  7.   

    dim mqtext="select * From t_A_20120723 WHERE ID > " & LastId.tostring你要用这个保证查询不会重复上一次的记录dim scn as new sqlconnection("SQLserver的连接串")
    dim scmd as sqlcommnd=scn.createcommand
    if MySqlDataReader.hasrow then
       while MySqlDataReader.read()
            for i=0 to MySqlDataReader.fieldcount-1
                values=values & MySqlDataReader.getxxx.tostring'如果是字符记得加单引号,如果日期要加#
                if i < MySqlDataReader.fieldcount-1 then values=values & ","
            end for
            itext="insert into table (" & Values & ")"
            scmd.commandtext=itext
            scmd.executnoquery
        end while
    endif
    我不会C#,你上网转一下就可以,以上只是一个简单的意思,如果只开一个线程,就让每次读数据就执行一次itext的SQL(你要打开一个SQL的连接),最好是一个读线程,把values加入一个list,另一个写线程负责把Values取出转成SQL,执行,删除values,另外,ID必须在写入之后递增,而且最好保存在文件里,以免断电关机影响同步
      

  8.   


    虽然看不太懂VB,但感谢prolee750607我用的是System.Data.SqlClient.SqlBulkCopy。
    把结果放进Table,然后做隐射,最后sqlbulk.WriteToServer(Table);
    感觉速度还行。
    不知道有用过的没?
      

  9.   

    没有用过啊,我这的是Mysqltosqlite、MysqltoMysql(不同的是我们需要每五分钟同步一次,所以放在封装成在服务里干活)
    我的方法其实就是先把mysql的select出来,不过保证读出的行是上次写入的行之后的内容,所以加了 Where Id > @Id(写一行就存一次这个值,通常是自动序列号)
    然后把读出来的值拼装成Sql:"insert into table (" & ValuesList & ")"然后用sqlcommand.executenoquery执行
    你也可以把Values放在List/ArrayList里
    这个Insert里有你刚刚读出的ID,运行成功一次,保存一次,下次Select时把最后的ID放在Where的@id里。
    System.Data.SqlClient.SqlBulkCopy这个我用用,谢谢啊。
      

  10.   

    我们也是循环读取并导入数据,本来也可以放在服务器事务中通过DBLink自动连接循环执行,但是非要开发成程序,要用代码实现。真实麻烦的很。我们读的目标库中的表每天都会新建一个模式动态生成的。以当天日期为表明。