我使用Talend将数据从Excel复制到SQL表。 在复制之前,我需要检查主键的列。如果密钥已存在于数据库中,我需要更新该记录,否则将该记录插入数据库中,并为其分配一个自动递增的密钥。
我该怎么做?
答案 0 :(得分:0)
您可以使用简单但缓慢的方式,只需使用t INSERT OR UPDATE
或UPDATE OR INSERT
(区别在于是否首先尝试更新或插入)选项在txxxSqlOutput组件中。大多数RDBMS组件都支持此功能,包括SQL Server组件:
如果您期望更多的更新而不是插入,那么Update or insert
选项的效果会更好,反之亦然。
或者,您可以事先查询数据库,然后将主键上的内部连接与您的数据流一起添加到数据库中。匹配显然是更新,然后明显插入拒绝(在tMap中的另一个数据流上启用Catch inner join reject
)。
tMap的配置如下:
第二种方式可以更高效,特别是在插入大型数据集时,因为第一个选项必须尝试逐行插入每一行,然后如果它失败则将其重写为更新语句。
第二个的另一个好处是它也可以包含在单个批处理/事务中,因为您不再需要故意捕获失败的插入/更新,然后更新/插入。这意味着您可以使您的工作更加健壮并更适当地处理错误。
答案 1 :(得分:0)
实际上我几天前正在处理同样的问题,这就是我的工作方式:
存储过程示例:
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