精华内容
下载资源
问答
  • 最近公司有一个项目需要对sqlserver增量数据进行一个数据迁移 2. 解决方案:针对时间戳进行增量回滚 参考了一个博客因为链接太长我就放在文章末了。(这篇文章主要是针对的mysql数据库,在调试过程中遇到很多坑,...

    1. 背景

    最近公司有一个项目需要对sqlserver的增量数据进行一个数据迁移

    2. 解决方案:针对时间戳进行增量回滚

    参考了一个博客因为链接太长我就放在文章末了。(参考博客的篇文章主要是针对的mysql数据库,而我遇到的问题是sqlserver的增量数据同步,在调试过程中遇到很多坑,我会在后面一一道出)

    参考了Azure的数据工厂中的增量复制模板(这个是找一个参考列,而这个参考列模板里给的是时间,我的个人理解还可以是其他的比如自增长的id那一列)

    其实这两个都是找到上次同步表的参考列的那个值,记录到中间表,然后找到新增数据参考列的最大值,将这个值与中间表中的上次同步的值做一个对比,多出来的数据就是新增的

    3. 工作开始时做一个说明

    这个一共涉及了三张表:

    源表:需要被同步的表,第一时间增加的表(可能是生产表)

    中间表:记录参考列的一张表(如果只同步一张表的话,那就只有一条数据,有两个表那就是两条数据,同理·········)

    目标表:同步的那张表,第二更新的表(可能是开发使用的表)

    4. 源表

    新建表

    USE [qstest]
    GO
    
    /****** Object:  Table [dbo].[im_message]    Script Date: 2021/4/26 14:52:20 ******/
    SET ANSI_NULLS ON
    GO
    
    SET QUOTED_IDENTIFIER ON
    GO
    
    CREATE TABLE [dbo].[im_message](
    	[id] [int] NOT NULL,
    	[sender] [varchar](45) NULL,
    	[send_time] [datetime] NOT NULL,
    	[receiver] [varchar](45) NOT NULL,
    	[content] [varchar](255) NOT NULL,
    	[is_read] [tinyint] NULL,
    	[read_time] [datetime] NULL,
    PRIMARY KEY CLUSTERED 
    (
    	[id] ASC
    )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
    ) ON [PRIMARY]
    GO
    
    ALTER TABLE [dbo].[im_message] ADD  DEFAULT (NULL) FOR [read_time]
    GO
    
    EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'消息发送者:SYSTEM' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'im_message', @level2type=N'COLUMN',@level2name=N'sender'
    GO
    
    EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'消息接受者:SYSTEM' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'im_message', @level2type=N'COLUMN',@level2name=N'receiver'
    GO
    
    EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'消息内容:SYSTEM' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'im_message', @level2type=N'COLUMN',@level2name=N'content'
    GO
    
    EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'消息时候被读取:0-未读;非0-已读:SYSTEM' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'im_message', @level2type=N'COLUMN',@level2name=N'is_read'
    GO
    
    EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'消息表' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'im_message'
    GO
    
    

    插入数据,每秒插入1条,一共插入10条 ,模拟生产数据

    #!/usr/local/python/bin/python
    # coding=utf-8
    '''
    @IDE :PyCharm
    @Author :Cayon_L
    '''
    
    import pymssql
    import time
    
    
    class TestDB:
        # --------------------------------------连接数据库------------------------------------------
        def __init__(self):
            try:
                self.conn  =pymssql.connect(
                    host='127.0.0.1',    # mysql的主机ip
                    user='sa',    # 用户名
                    password='***',  # 数据库密码
                    database='****',  # 数据库名
                    charset='utf8',  # 字符集
                )
                self.cursor = self.conn.cursor()
                print('数据库链接成功!')
            except Exception as e:
                print('数据库链接错误:', e)
        def query(self):
            # --------------------------------------SQL语句块【开始】------------------------------------------
            try:
    
                sql2 = "INSERT INTO im_message VALUES(%s,'system', CONVERT(varchar,GETDATE(),120),'etl1','KettleTest',0,NULL);"
                info = i
                if i <800:
                    self.cursor.execute(sql2,info)
                # SQL提交
                    self.conn.commit()
                    print('数据库操作成功')
                else:
                    print('数据库操作失败')
            except Exception as e:
                print('数据库操作失败', e)
        # --------------------------------------SQL语句块【结束】------------------------------------------
     
        # --------------------------------------数据库连接关闭------------------------------------------
        def end(self):
            try:
                self.cursor.close()
                self.conn.close()
                print('数据库成功关闭!')
            except Exception as e:
                print('数据库关闭失败:', e)
     
     
    if __name__ == '__main__':
        j=0
        i = 328  
        while True :
            if j<10:
                test = TestDB()
                test.query()
                test.end()
                j = j+1
                i = i + 1
                time.sleep(1)
            else:
                break
    

    5. 作业流程

    1. 开始组件
    2. 建时间戳中间表
    3. 获取中间表的时间戳,并设置为全局变量
    4. 删除目标表中时间戳及时间戳以后的数据
    5. 抽取两个数据表的时间戳及时间戳以后的数据进行比对,并根据比对结果进行删除、新增或修改操作
    6. 更新时间戳

    6. 作业概览

    使用的kettle版本:8.2,具体安装流程可以百度

    6.1 连接数据库

    打开Spoon工具,新建作业,然后在左侧主对象树DB连接中新建DB连接。创建连接并测试通过后可以在左侧DB连接下右键共享出来。

    6.2 建时间戳中间表

    创建中间表etl_temp,并插入初始的时间戳字段。因为该作业在生产环境是循环调用的,该步骤在每一个同步周期中都会调用,所以在建表时需要判断该表是否已经存在,如果不存在才建表。

    PS:如果要设置多张表同步,那么需要将id改为name,并将值改为表名即可

    6.3 获取时间戳并设为变量

    新建一个转换,在转换中使用表输入、字段选择和设置变量三个组件

    表输入:找到中间表源表参考列最大值的那条(下面这个是一张表的同步,如果是多张表那么根据上面的ps操作即可)

    这里面用到了一个字段选择,因为kettle转换时间的时候后面多了很多0(标准时间戳也是会有很多0,目前没找到为什么)

    下面这个是将输入的那条最大值作为变量传出来

    6.4  删除目标表中时间戳及时间戳以后的数据

      防止机器不稳定宕机,这样数据没更新成功,重启之后就会把目标表宕机没更新时间戳的那部分数据给删掉,开始数据的重新增量复制,保证了作业的稳定性

    6.5 增量数据的抽取,删除,更新

    原始表输入:

    目标表输入:

    如果有新插入的,那就执行表输出

    “Kettle有一个插入/更新组件,但是据网友介绍这个组件性能低下,每秒最多只能同步几百条数据,所有我对插入和更新分别作了不同的处理。插入使用表输出组件;更新使用更新组件。
    为了进一步提升同步效率,我在表输出组件使用了多线程(右键>改变开始复制的数量),使同步速度达到每秒12000条。Switch组件和表输出组件中间的虚拟组件(空操作)也是为了使用多线程添加的。”

    如果有更新那就执行更新:

    如果有删除,那就执行删除操作

    6.6.  更新时间戳

    update etl_temp set time_stamp=(SELECT top(1)  SEND_TIME FROM im_message ORDER BY SEND_TIME desc) where id='1';

    7. 发送邮箱

    具体可以参考:Kettle配置发送邮件

    此处附上调试邮箱时收到的邮件

    8. 调度

    9. 测试

    具体测试结果如下:

    10. 参考

    我主要是参考使用Kettle实现数据实时增量同步,这篇博客做的是mysql数据的增量复制

    mysql和sqlserver有一些不一样的地方:

    1,时间戳,sqlserver中是datetime类型

    2,时间类型传变量的时候不知道为啥kettl读取出来的数据会在后面加好几个0(费解)

    还有一些不一样的地方具体忘了

    展开全文
  • 抽取增量数据 select ID,NAME, CASE WHEN __$operation = 1 then 1 else 0 end as isdeleted into #tb_import from ( select row_number() over (partition by id order by [ __$...
    --创建测试库
    create database test;
    --创建配置表
    create table test..time_config(tb varchar(20) PRIMARY KEY,enddate binary(10));
    --创建业务表
    create table test..TB_s (ID INT PRIMARY KEY,NAME VARCHAR(20)); --原表
    create table test..TB_t (ID INT PRIMARY KEY,NAME VARCHAR(20),ISDELETED INT); --目标表
    
    --给配置表初始时间
    insert into test..time_config
    select 'TB_t' as tb,max(start_lsn) as enddate from test.[cdc].[lsn_time_mapping]
    
    --开启cdc
    use TEST
    GO
    EXEC sys.sp_cdc_enable_db --开启库级别cdc
    EXEC sys.sp_cdc_enable_table @source_schema = 'dbo', @source_name = 'TB_s', @role_name = null; --开启表cdc
    GO
    
    
    --增量实现存储过程
    
    create proc cdc_tb as
    declare 
    @time_begin binary(10),
    @time_end binary(10)
    
    select @time_begin=max(enddate) from test.dbo.time_config    --上次结束时间,即本次开始时间
    select @time_end=max(start_lsn) from test.[cdc].[lsn_time_mapping]    --获取最大时间,即本次结束时间
    
    --抽取增量数据
    select ID,NAME,CASE WHEN __$operation=1 then 1 else 0 end as isdeleted into #tb_import from(
    select row_number()over(partition by id order by [__$start_lsn] desc,__$seqval,__$operation desc ) as rn,* 
    from test.[cdc].[dbo_TB_s_CT] 
    where [__$start_lsn]>@time_begin and [__$start_lsn]<=@time_end) t1 where rn=1;
    
    delete from test..TB_t where exists (select * from #tb_import);
    insert into test..TB_t select * from #tb_import;
    
    update test.dbo.time_config set enddate= @time_end where tb='TB_t';--将本次结束时间存入配置表;
    declare @count int
    select @count=count(1) from #tb_import 
    print('更新'+cast(@count as varchar(10))+'条记录')
    
    --测试添加:
    insert into TB_s
    select 1,'aaa'
    --修改
    update TB_s set name='bbb' where id=1
    --删除
    delete from TB_s where id=1
    
    select * from TB_s
    
    exec cdc_tb --创建job 定时作业
    
    select * from TB_t
    
     

     

    转载于:https://www.cnblogs.com/zzchao/p/11430092.html

    展开全文
  • 今天就说说SQL Server 增量数据同步。当公司的业务数据量越来越多的时候,数据分析部门总想用来做报表,或者提炼出有用的运营数据。通常,相关负责人希望将各个业务系统、各种不同结构的数据同步到数据仓库、数据湖...

    今天就说说 SQL Server 增量数据同步。当公司的业务数据量越来越多的时候,数据分析部门总想用来做报表,或者提炼出有用的运营数据。通常,相关负责人希望将各个业务系统、各种不同结构的数据同步到数据仓库、数据湖等。

     

    若是其他类型数据库,多部署在 Linux 环境中,同步数据有较多及成熟的方案。

     

    SQL Server 有哪些增量同步方案呢?

     

    方案一:更改跟踪(Chang Tracking)

    更改跟踪是表级别的跟踪,记录的只是行已更改的事实,而不是行更改的次数或任何中间更改的值。因为只存储的行标识符,这就要求表必须有主键。当对表进行DML操作时,系统表都会将主键记录下来,生成自己的行版本。

     

    那具体的行数据在哪呢?当然还是在原来的表了,只要将跟踪的主键与原表关联,可以找到新增和最后一次更改的行记录。对于删除的记录,原表没有了,我们知道主键就可以同步到目标表进行删除。通过记录版本,每次可同步最近的操作。

     

    图片

    CT原理图

     

    不过,更改跟踪在实际工作中,很少人会使用。我想有几个原因:

    • 更改的中间值没有记录,对数据有严格的事务属性不适用。

    • DML频繁,也影响到跟踪表记录的DML频繁,也会影响一些性能。

    • 了解的人很少,毕竟几乎所有的第三方同步工具,都是基于变更数据捕获(CDC),而不是更改跟踪。

    • 更改跟踪不算增量同步一种,相当于同步当前一次快照记录。

     

     

    方案二:变更数据捕获(Change Data Capture,CDC)

    CDC 应该是多少大数据开发人员了解的,CDC 也是表级别的数据同步。CDC 同样有一张表记录跟踪,当对源表进行 DML 时,在事务日志会记录相关操作信息。变更数据捕获代理使用异步进程读取事务日志,将相关操作结果应用到副本表(捕获实例表)中,这样就完成了对源表操作的记录跟踪。即使数据库恢复模式处于简单模式,也同样适用。CDC 原理如下图。

     

    图片

    CDC 原理

     

    对于增量跟踪,应用程序在每次操作时,记录相应的时间或者事务日志序列号(LSN),下次读取大于该 LSN 即可。既然是读取数据库的事务日志,CDC 进程逻辑嵌入在存储过程 sp_replcmds中(事务复制也使用相同的进程)。

     

    CDC 是比较常用的,但是当对表新增字段的时候,新字段是不会跟踪的。一般的解决方法是:新增字段后,对原表再启用一个CDC跟踪实例表,待原来的跟踪记录同步完成后,删除原跟踪实例表。字段新增方案其实还有一种,我这有一个脚本(如下链接)。当新增字段后,执行链接中脚本,将生产新的一个临时CDC跟踪实例,根据该实例生成的存储过程信息,替换原来的存储过程,然后禁用该新实例。这样增加字段后就不必等数据同步完成,继续使用表第一次启用CDC的系统对象。

    https://github.com/hzc2012/SQLServer/blob/master/Scripts/Sync_CDC_Table_Columns_To_CT

     

     

    方案三:UpdatedTime 字段

    该方案也是非常普遍的同步方案。表中新增一个时间字段,默认值为当前时间 GETDATE()。然而该字段不像 MySQL 可以自动更新。只能添加一个更新触发器,当行数据被更改时,UpdatedTime 更新为当前时间。如下示例。

    CREATE TABLE [dbo].[TestTab](
      ID INT IDENTITY(1,1) NOT NULL,
      Name VARCHAR(50) NOT NULL,
      UpdatedTime DATETIME NOT NULL DEFAULT(GETDATE())
    )
    GO
    CREATE TRIGGER tr_TestTab_update  
    ON dbo.TestTab  
    AFTER UPDATE   
    AS
    BEGIN
      UPDATE t SET UpdatedTime=GETDATE() 
      FROM dbo.TestTab t 
      INNER JOIN inserted i ON t.id=i.id
    END
    GO

    数据的同步则按照时间进行增量查询,捕获相应的变更数据。对于触发器,相信大家都比较抵制,触发器每次都得进行一次表关联更新,增加了系统资源开销。若每次更新表数据都更新一个时间字段也不合适。那如何是好啊!下面,我们使用另一种方案!

     

    方案四:行版本 rowversion / timestamp

    该方案在大多数同学中还不被熟悉,估计只有较专业的 SQL Server DBA 有可能了解。说起 timestamp 可能很多同学都听过,在 SQL Server 中,timestamp 只是 rowversion 的一个同义词(可以说是别名)。timestamp 是 SQL Server 早期版本使用的名称, timestamp 已过时,在以后的 SQL Server 版本中将被删除。接下来,我们就使用 rowversion 吧。

     

    rowversion 是数据库中自动生成的唯一二进制数字的数据类型。rowversion 通常用作给表行加版本戳的机制。存储大小为 8 个字节。rowversion 数据类型只是递增的数字,不保留日期或时间。不可为空的 rowversion 列在语义上等同于 binary(8) 列。可为空的 rowversion 列在语义上等同于varbinary(8) 列。

     

    我们做一个示例,插入5行数据。

    CREATE TABLE TestTab (id INT NOT NULL,rv ROWVERSION );
    GO
    INSERT INTO TestTab(id) VALUES(1)
    GO 5
    SELECT * FROM TestTab
    GO
    
    id  rv
    1  0x00000000000007D5
    1  0x00000000000007D6
    1  0x00000000000007D7
    1  0x00000000000007D8
    1  0x00000000000007D9
    
    SELECT @@DBTS AS 当前RV,MIN_ACTIVE_ROWVERSION() AS 下一个可用RV
    0x00000000000007D9  0x00000000000007DA

    使用系统变量和函数 @@DBTS 和 MIN_ACTIVE_ROWVERSION() 查看数据库的行版本号。也可以创建多个表进行验证,行版本是数据库范围级别的,不过增量同步数据时,还是按表将行版本存储起来,待下一次增量读取表记录。(是不是类似方案三?)

     

     

    总结:

    SQL Serve 中的增量数据同步方案,相对其他数据库来说是有点损耗性能的,毕竟闭源,只能连接数据库进行数据查询操作。不过,也有较多的第三方工具做的不错,也是基于上面的几种方案进行数据增量抽取。如 Oracle GoldenGate、Debezium 是基于CDC的,而 alibaba/DataX 对于SQL Server 是基于查询抽取数据的。根据不同的业务场景或架构情况,选择符合自己的方案才是最好的。

     

     

    展开全文
  • Scala连接Mysql数据库和Sqlserver数据库 Mysql和Sqlserver源数据库单表数据量超过200G,现在需要把数据搬运到HDFS上存储,释放源数据库存储空间。这里采用Scala开发Spark程序,按照索引ID增量抽取数据插入到hive...

    Scala连接Mysql数据库和Sqlserver数据库


    Mysql和Sqlserver源数据库单表数据量超过200G,现在需要把数据搬运到HDFS上存储,释放源数据库存储空间。这里采用Scala开发Spark程序,按照索引ID增量抽取数据插入到hive数据库中,计划每次增量抽取300万条数据,并且每次存储最大ID到一张记录表中。下次抽取的时候首先获取记录表中的最大ID作为数据抽取的起始ID,起始ID加300万与源数据库表中的最大ID进行比较,如果小于源数据库表中最大ID,则起始ID加300万的值作为数据抽取结束ID,如果大于源数据库表中最大ID,则取源数据库表中最大ID为数据抽取结束ID。

    如下图所示:
    每次抽取300万条数据,并且每次存储最大ID到一张记录表中,在最大ID基础上实现每次增量抽取300万条数据到Hive数据库表中。
    在这里插入图片描述

    下面详细记录了Scala连接Mysql数据库和Sqlserver数据库,增量抽取数据存储到Hive数据库的代码。连接Mysql数据库采取了单线程抽取数据,连接Sql

    展开全文
  • ETL中的数据增量抽取机制研究,数据仓库
  • sqoop import --driver com.microsoft.sqlserver.jdbc.SQLServerDriver --connect "jdbc:sqlserver://IP地址:1433;database=TS_Test" --username sa --password Test6530 --table data --target-dir '/user/hive/...
  • 1.SqlServer/MySQL全量增量导入HDFS/Hive, 2.HDFS导入hive 3.hdfs导出到SqlServer/MySQL 4.hive导出到hdfs 5.hive导出到SqlServer/MySQL 6.还有以上过程的注意事项、操作过程中可能遇到的错误、改正方法 如...
  • 实现SQL Server到MySQL的表增量同步

    千次阅读 2017-01-01 15:10:11
    本教程是为了实现SQLSERVER数据库表中数据增量同步到MySQL数据库,并每天定时执行一次。 注:只实现了新增与更新数据,源库中删除的数据未实现同步 1、前期准备 开始之前,请记得自行安装JDBC,安装步骤百度搜索即可...
  • CDC(变更数据捕获)最初是在ORACLE中使用的,微软在MS SQLServer2008中引入了这项技术,在此之前对数据变更的捕获通常使用触发器、时间戳等低效高成本的功能来实现,尤其是通过触发器实现数据修改的捕获有很多弊端...
  • 关于sql server 2012 CDC 使用数据库增量数据的提取
  • 目前的问题:数据库A中有一批表(A1,A2,A3.......),现在需要将其转移到数据库B中,由于A库中 表的数据在不停的增加,现在想做增量将A库中的数据导入到B库中,就需要判断哪些数据时新增的,目前想到的解决方法有一下三...
  • select (case CT.sys_change_operation when 'I' then 'INSERT' when 'U' then 'UPDATE' when 'D' then 'DELETE' end) as rowtype ,CT.sys_change_version as rowVersion,CT.主键 from ( select 主键,max(sy...
  • sqlserver数据实时同步至kafka

    万次阅读 2019-01-09 17:35:36
    在处理实时数据时,需要即时地获得 数据库 表中数据的变化,然后将数据变化发送到Kafka中。这篇文章将介绍如何使用Kafka Connector完成这一工作。当获取实时数据时,数据源需要...ETL之增量抽取方式:https://ww...
  • sqlserver随机取记录

    2020-01-08 09:50:42
    本文转载自:...sqlserver随机取记录 2009年03月09日 星期一 下午 06:03 SqlServer本身并没有提供随机读取记录的功能,但我们可以通过一些方法来实现这个目的。本文介绍了其中几种方法并比较了各自的...
  • sqlserver导入oracle工具,
  • 设计需求:本地库抽取远程库数据数据进行数据同步 ,只适用于sql server数据库 CREATE PROC [dbo].[DATA_RSYNC] AS declare @id INT ;--某个表中最大ID(本地表) declare @id2 int; --某个表中最大ID远程表) ...
  • Flume抽取SQL Server设计方案

    千次阅读 2018-05-28 10:37:59
    (1)使用flume抽取sql server :board表中的数据,flume只能增量抽取,无法处理更新的数据 (2)为mysql创建 trigger,通过trigger将有变更的数据存到A表中 (3)使用flume抽取A表有更新的数据 (4)在Spark Streaming 中使用...
  • 为了满足数据迁移和数据抽取的业务需要,使得有机会在数据库层面上直接实现增量抽取功能,ORACLE综合性能和场景需要,在数据库引擎层面直接集成了CDC功能,由于提供了类似API的功能接口,变更数据捕获和更改跟踪均不...
  • 最近调查了一下从数据库中增量抽取数据的几种方案。下面是一个比较粗的结论。方法1:基于时间戳以某个时间字段为条件,检出新增数据。适用条件:表中有时间字段,并且是事件型的数据,不需要反映数据的删除和更新。对...
  • 我的需求是从sqlserver(reader)导入到MySQL(writer) 查看sqlserver该配置的模板 查看MySQL该配置的模板 4、进行配置 进入到job目录下,新建文件,(可以以自己要导入的表名命名) 5、 python /opt/datax/bin/...
  • 1 客户方SqlServer的表每5分钟会采集到hive中,每5分钟作为一个分区 2 编写Hsql脚本读取分区表数据,进行数据转换,存到Hive的结果分区表中, 3 将结果数据同步到客户的sqlServer目标表中。 其中,没5分钟采集到...
  • https://www.cnblogs.com/maikucha/p/9039205.html
  • 然后hana数据库会自动创建一张与sqlserver相对应的一张user表,并且数据也会同时同步过来。 最后一步 : 注意:一定是 先执行上面的定时任务 后,再做这个操作,不然会报错 把模板表导入到我们创建的hana的...
  • nbspPHP资料如何将数据从SQLServer实时或定时同步到MySQL数据库.doc5页本文档一共被下载:次,您可全文免费在线阅读后下载本文档。 下载提示1.本站不保证该用户上传的文档完整性,不预览、不比对内容而直接下载产生...
  • 由于日志表的数据量庞大,我只需要从某一特定时间开始对业务系统产生的日志抽取出来,而且需要每5分钟(假定)进行抽取一次,把在这5分钟内产生的日志信息抽到我的表里面,产生一个增量抽取的效果。解决过程在网上找了...
  • kettle利用时间戳(timestamp)做增量抽取

    万次阅读 多人点赞 2018-04-16 14:18:13
    Max(填表日期)就可以获到本次增量抽取过来的最近时间,sysdate,来获取本次的操作时间 再将其插入到times表里     通过作业把他们组合到一块 详细步骤:start用于开始, 在第二个控件转化里面 把刚才做的那个...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 4,370
精华内容 1,748
关键字:

sqlserver增量抽取

友情链接: embed.tar.gz