【问题标题】:SSIS Improve upsert methodSSIS 改进 upsert 方法
【发布时间】:2016-07-08 07:36:29
【问题描述】:

我有 100,000 行的数据库表,每周使用 SSIS 包从 CSV 导入。 通常会更新,但有时可以添加行。

我在更新行期间看到临时表出现一些异常 - 我不知道为什么?以及如何从暂存表更新到目标表?

这是合并代码:

MERGE INTO [PWCGFA_BG].[dbo].[Bank_Guarantees]  WITH (HOLDLOCK) AS bg 
USING [PWCGFA_BG].[dbo].[stagingBG] AS stgbg
    ON bg.IATA_CODE = stgbg.IATA_CODE
WHEN MATCHED THEN 
    UPDATE  set  
        bg.LEGAL_NAME=stgbg.LEGAL_NAME,
    bg.TRADING_NAME=stgbg.TRADING_NAME,
    bg.COUNTRY=stgbg.COUNTRY,
    bg.CURRENCY=stgbg.CURRENCY,
    bg.LANGUAGE=stgbg.LANGUAGE,
    bg.STATUS=stgbg.STATUS,
    bg.BANK_NAME=stgbg.BANK_NAME,
    bg.BANK_GUARANTEE_AMOUNT=stgbg.BANK_GUARANTEE_AMOUNT,
    bg.BANK_GUARANTEE_CURRENCY=stgbg.BANK_GUARANTEE_CURRENCY,
    bg.BANK_GUARANTEE_EXPIRY_DATE=stgbg.BANK_GUARANTEE_EXPIRY_DATE,
    bg.ACCREDITATION_DATE=stgbg.ACCREDITATION_DATE,
    bg.CLASS_PAX_OR_CGO=stgbg.CLASS_PAX_OR_CGO,
    bg.LOCATION_TYPE=stgbg.LOCATION_TYPE,
    bg.XREF=stgbg.XREF,
    bg.IRRS=stgbg.IRRS,
    bg.TAX_CODE=stgbg.TAX_CODE,
    bg.COUNTRY_CODE=stgbg.COUNTRY_CODE,
    bg.CITY=stgbg.CITY,
    bg.DEF=stgbg.DEF,
    bg.OWN_SHARE_CHANGE=stgbg.OWN_SHARE_CHANGE
WHEN NOT MATCHED BY bg THEN
    INSERT (IATA_CODE,LEGAL_NAME,TRADING_NAME,COUNTRY,CURRENCY,LANGUAGE,STATUS,BANK_NAME,BANK_GUARANTEE_AMOUNT,BANK_GUARANTEE_CURRENCY,BANK_GUARANTEE_EXPIRY_DATE,ACCREDITATION_DATE,CLASS_PAX_OR_CGO,LOCATION_TYPE,XREF,IRRS,TAX_CODE,CITY,DEF,OWN_SHARE_CHANGE)
    VALUES (stgbg.IATA_CODE,stgbg.LEGAL_NAME,stgbg.TRADING_NAME,stgbg.COUNTRY,stgbg.CURRENCY,stgbg.LANGUAGE,stgbg.STATUS,stgbg.BANK_NAME,stgbg.BANK_GUARANTEE_AMOUNT,stgbg.BANK_GUARANTEE_CURRENCY,stgbg.BANK_GUARANTEE_EXPIRY_DATE,stgbg.ACCREDITATION_DATE,stgbg.CLASS_PAX_OR_CGO,stgbg.LOCATION_TYPE,stgbg.XREF,stgbg.IRRS,stgbg.TAX_CODE,stgbg.CITY,stgbg.DEF,stgbg.OWN_SHARE_CHANGE)
WHEN NOT MATCHED BY stgbg THEN
    DELETE

【问题讨论】:

  • 什么是“一些经验”?例外?您需要告诉我们例外情况以及一些源数据。
  • 几个例子,我的意思是对于更新,他们使用暂存表,但我不知道他们如何从暂存到目标数据库插入,在我的情况下,我在 ssms 中创建了一个存储过程以进行更新, 并在 OLE DB 命令中执行
  • 也许您应该将您的 sp 转换为从临时表执行 MERGEBank_Guarantees 而不仅仅是 UPDATE。在这种情况下,您可以摆脱 LookupBank_Guarantees Destination
  • 但是如果查找 Upsert 不是最佳实践,为什么很多文章都使用它?
  • @BKChedlia 它在哪里说不是最佳实践?不明白为什么

标签: ssis


【解决方案1】:

如果您的源(暂存)表和目标表在同一服务器上,您可以将MERGE 语句与执行 SQL 任务一起使用,这比使用逐行操作的查找更快且非常有效。

但如果目的地在不同的服务器上,您有以下选择

  1. 通过 OLEDB 命令(UPDATE 语句)使用查找来更新匹配的行
  2. 使用合并连接(使用 LEFT OUTER JOIN)来识别新的/匹配的记录,然后使用条件拆分来插入或更新记录。这与查找相同,但速度更快。
  3. 在目标数据库中创建一个临时表,将数据从登台转储到该表,然后使用 MERGE 语句,这比使用查找要快。

【讨论】:

  • 我尝试了这个合并(上面,我编辑了我的帖子)但我有这个错误消息:[执行 SQL 任务]错误:执行查询“合并到 [PWCGFA_BG].[dbo].[Bank_Guar] ...”失败并出现以下错误:“'bg' 附近的语法不正确。”。可能的失败原因:查询有问题,“ResultSet”属性设置不正确,参数设置不正确,或者连接没有正确建立。
  • 将语句从 WHEN NOT MATCHED BY BG THEN 更改为 WHEN NOT MATCHED BY TARGET THEN 和 WHEN NOT MATCHED BY stgbg THEN 更改为 WHEN NOT MATCHED BY SOURCE THEN,您需要使用关键字 TARGET 和 SOURCE not别名,希望对您有所帮助
  • 谢谢,我做到了,当我删除行然后添加新行并编辑行时,我遇到了另一个问题:MERGE 语句多次尝试更新或删除同一行。当目标行匹配多个源行时会发生这种情况。 MERGE 语句不能多次 UPDATE/DELETE 目标表的同一行。优化 ON 子句以确保目标行最多匹配一个源行,或使用 GROUP BY 子句对源行进行分组。
  • 那是因为你可能在目标表中有多次IATA_CODE,可能你需要添加额外的条件来匹配一个目标行。
  • 你是对的,我在 csv 文件中发现了错误的数据,没有 unik id...谢谢 MSBI-Geek
猜你喜欢
  • 2010-11-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-12-02
  • 1970-01-01
  • 1970-01-01
  • 2013-08-08
相关资源
最近更新 更多