在Talend中从Excel复制到SQL时插入/更新

时间:2014-07-17 15:14:32

标签: sql sql-server excel talend upsert

我使用Talend将数据从Excel复制到SQL表。 在复制之前,我需要检查主键的列。如果密钥已存在于数据库中,我需要更新该记录,否则将该记录插入数据库中,并为其分配一个自动递增的密钥。

我该怎么做?

2 个答案:

答案 0 :(得分:0)

您可以使用简单但缓慢的方式,只需使用t INSERT OR UPDATEUPDATE OR INSERT(区别在于是否首先尝试更新或插入)选项在txxxSqlOutput组件中。大多数RDBMS组件都支持此功能,包括SQL Server组件:

SQL Server Upsert options

如果您期望更多的更新而不是插入,那么Update or insert选项的效果会更好,反之亦然。

或者,您可以事先查询数据库,然后将主键上的内部连接与您的数据流一起添加到数据库中。匹配显然是更新,然后明显插入拒绝(在tMap中的另一个数据流上启用Catch inner join reject)。

Faster way to upsert data

tMap的配置如下:

tMap configuration to allow for more performant upserts

第二种方式可以更高效,特别是在插入大型数据集时,因为第一个选项必须尝试逐行插入每一行,然后如果它失败则将其重写为更新语句。

第二个的另一个好处是它也可以包含在单个批处理/事务中,因为您不再需要故意捕获失败的插入/更新,然后更新/插入。这意味着您可以使您的工作更加健壮并更适当地处理错误。

答案 1 :(得分:0)

实际上我几天前正在处理同样的问题,这就是我的工作方式:

  1. 将所有数据从excel加载到sql临时表(临时表必须与数据库中的表具有相同的结构,并且必须在同一数据库中创建)
  2. 创建一个存储过程,将临时表的主键与数据库表进行比较(如果不存在,则插入其他更新)
  3. 在ETL任务中调用存储过程。
  4. 存储过程示例:

       CREATE PROCEDURE [dbo].[up_ImportProductsData]
        AS
        BEGIN
          @Product_PK int,     //Product primary key
          @Product_Name NVarchar(30) // Product name
    
        // we create a cursor on product temporay table
        DECLARE c_Product CURSOR FOR
        SELECT Product_PK,
               Product_NAME,
        FROM Product_tempory_table
    
        //We open the cursor to check product pk one by one
        OPEN c_Product CURSOR
        FETCH c_Product CURSOR INTO 
        @Product_PK, @Product_Name 
        WHILE @@fetch_status=0
    
        //Checking if the Product_PK exits
        BEGIN
    
        //If the PRimary key doesnt exists then we insert it
         IF NOT EXISTS(SELECT * FROM dbo.Product_Table
        WHERE Product_PK=@Product_PK)
        BEGIN
                INSERT INTO dbo.Product_Table
                        ( 
                           Product_PK,
                           Product_NAME
                        )
                VALUES  ( 
    
                          @Product_PK, @Product_Name
                        )  
           END
    
        //If The primary key exists we update it
        ELSE
          BEGIN
             UPDATE dbo.Product_Table
             SET    Product_NAME=@Product_Name 
    
             WHERE Product_PK= @Product_PK
    
          END
        FETCH c_Product INTO 
        @Product_PK, @Product_Name 
        END
        CLOSE c_Product
        DEALLOCATE c_Product 
    
    END