在Trigger中循环?

时间:2010-11-22 06:07:28

标签: sql-server-2008 triggers sqlbulkcopy

我有以下情况,

有四个表COUNTRY,STATE,CITY,STREET
我有excel文件,上面有上述记录......截至目前可能有2000行。

我使用SqlBulkCopy将数据导入临时表,让我们将表命名为IMPORT。

我在IMPORT表上写了一个插入触发器来获取插入的记录 然后拆分国家,州,城市,街道然后将它们插入相应的表格。

在此触发器中,我必须进行一些条件检查,例如,如果COUNTRY名称已经存在,则返回COUNTRY_ID,否则插入它并获取新的COUNTRY_ID。

如果Excel文件只有一行,则上述方法有效。 一旦我将原始Excel用于导入,我就知道触发器中的以下语句失败“从INSERTED中选择国家”,因为sqlbulkcopy使INSERTED具有多个记录。

表格结构

COUNTRY

  • Country_ID
  • COUNTRY_NAME

STATE

  • State_ID
  • Country_ID
  • STATE_NAME

CITY

  • City_ID
  • State_ID
  • COUNTRY_ID
  • CITY_NAME

STREET

  • Street_ID
  • City_ID
  • State_ID
  • COUNTRY_ID
  • STREET_NAME

IMPORT

  • COUNTRY_NAME
  • STATE_NAME
  • CITY_NAME
  • STREET_NAME

那么我可以在触发器中使用循环语句来遍历INSERTED中的所有记录吗?

或者如何以最佳方式解决这个问题?

注意:由于他们已经在使用它,我无法控制这些表结构及其关系。

提前致谢。

2 个答案:

答案 0 :(得分:2)

您的第一个问题是,您绝不应该考虑将记录集循环作为首选。它几乎总是错误的选择,因为它在这里。你的下一个问题是触发器不是一次处理整个记录集,而是从你的描述中处理,我敢打赌你写它假设它一次处理一条记录。您需要基于集合的流程。

在你的触发器中你可能需要这样的东西,它会插入所有未插入国家表的国家(这假设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)

您还可以使用存储过程而不是触发器从登台表插入真实表。

答案 1 :(得分:1)

从不将任何此类处理密集型任务放入用于批量加载的表的触发器中!并且永远不会开始像游标一样将循环和类似的东西放入触发器 - 触发器必须小巧,精简和平均 - 只需快速插入审计表或其他东西 - 但它应该做举重!

你应该做的是:

  • 使用SqlBulkLoad尽快将您的数据导入到临时表中,没有触发器或任何内容
  • 然后基于该登台表,通过拆分列值和类似的东西进行必要的后处理

否则,你完全杀掉SqlBulkLoad拥有的任何好处......

要做后期处理(比如确定给定Country_ID的{​​{1}}),你不需要游标或任何这些邪恶的东西 - 只需使用标准的,运行的你桌子上的{mill Country陈述 - 这就是你所需要的。