在Trigger中循環?

sqlbulkcopy sql-server-2008 triggers

我得到以下情況,

有四個表COUNTRY,STATE,CITY,STREET
我有excel文件,上面有上述記錄。截至目前,可能有2000行。

我使用SqlBulkCopy將數據導入臨時表,讓我們將表命名為IMPORT。

我在IMPORT表上寫了一個插入觸發器,它獲取插入的記錄並拆分國家,州,城市,街道然後將它們插入到相應的表中。

在此觸發器中,我必須進行一些條件檢查,例如,如果COUNTRY名稱已經存在,則返回COUNTRY_ID,否則插入它並獲取新的COUNTRY_ID。

如果Excel文件只有一行,則上述方法有效。一旦我把原始的Excel用於導入我發現它在觸發器中的以下語句失敗“從INSERTED中選擇國家”,因為sqlbulkcopy使INSERTED具有多個記錄。

表結構

國家

  • COUNTRY_ID
  • 國家的名字

  • STATE_ID
  • COUNTRY_ID
  • STATE_NAME

  • City_ID
  • STATE_ID
  • COUNTRY_ID
  • 城市名

  • Street_ID
  • City_ID
  • STATE_ID
  • COUNTRY_ID
  • 街道名稱

進口

  • 國家的名字
  • STATE_NAME
  • 城市名
  • 街道名稱

那麼我可以在觸發器中使用循環語句來循環INSERTED中的所有記錄嗎?

或者如何以最好的方式解決這個問題?

注意:由於他們已經在使用它,我無法控制這些表結構及其關係。

提前致謝。

一般承認的答案

您的第一個問題是,您絕不應該考慮將記錄集循環作為第一選擇。它幾乎總是錯誤的選擇,因為它在這裡。你的下一個問題是,觸發器不是一次處理整個記錄集,而是從你的描述中處理,我敢打賭你寫的它假設它一次處理一條記錄。您需要一個基於集合的流程。

在你的觸發器中你可能需要這樣的東西,它會插入所有未插入國家表的國家(這假設country_Id是一個整數標識列):

Insert country (country_name)
select country_name 
from inserted i
where not exists 
  (select * from country c 
   where c.country_name = i.country_name)

您還可以使用存儲過程而不是觸發器從登台表插入實際表。


熱門答案

絕不會將任何此類處理密集型任務放入用於批量加載的表的觸發器中!而從來沒有開始將像光標之類的東西環插入觸發器-觸發一定要小,精簡的意思是-只是一個快速插入到一個審計表或東西-但它應該做的繁重!

你應該做的是:

  • 使用SqlBulkLoad盡快將數據導入到臨時表中,沒有觸發器或任何東西
  • 然後基於該臨時表,通過拆分列值和類似的東西來進行必要的後處理

否則,你完全殺掉了SqlBulkLoad擁有的任何好處。

要做這個後期處理(比如確定給定Country Country_ID ),你不需要游標或任何這些邪惡的東西 - 只需在你的桌子上使用標準的,普通的UPDATE語句 - 這就是你的全部需要。



許可下: CC-BY-SA with attribution
不隸屬於 Stack Overflow
這個KB合法嗎? 是的,了解原因
許可下: CC-BY-SA with attribution
不隸屬於 Stack Overflow
這個KB合法嗎? 是的,了解原因