1

我创建了一个批处理文件来运行 SqlMetal 并生成 Linq2Sql 数据类,签入触发构建的源代码控制等...我希望在 Sql Server 2005 中发生 DDL 更改时运行此脚本。

通过 xp_cmdshell 运行批处理文件可以在触发器之外正常工作,如下所示:

exec master..xp_cmdshell 'd:\dev\db_triggers\generatedataclasses.bat', no_output

但是当它作为触发器运行时,连接数据库总是超时,导致所有DDL失败。这是我的触发器:

CREATE TRIGGER [Trig_SqlMetal]
ON DATABASE
FOR DDL_DATABASE_LEVEL_EVENTS 
AS
exec master..xp_cmdshell 'd:\dev\db_triggers\generatedataclasses.bat', no_output

我正在寻找关于两点的建议:

  1. 完成这项工作。出于某种原因,它在触发器中时总是失败,而不是在触发器中时不会。似乎与安全无关,因为它在两种情况下都作为 LocalSystem 运行。
  2. 使这种情况异步发生,以便 SqlMetal 中的故障和超时不会导致 DDL 更新失败。我试过用另一个和“start cmd.exe /c otherbatch.bat”包装批处理文件,但是当通过sql server运行时,它似乎忽略了开始(在DOS下工作正常)。我当然可以编写一个轮询过程来查看一些表和拾取事件,但我希望这是基于触发器的,以使其不那么复杂(或者我是否在做相反的事情:))。
4

1 回答 1

3

您的批处理可能被阻止,因为它尝试查询有关正在创建的表的数据,但它们仍被锁定在事务中(触发器是 SQL Server 为任何 DDL/DML 语句启动的隐式事务的一部分),这只会完成触发器完成后。我所知道的在 SQL Server 2005 或更高版本中异步执行的唯一“几乎”实用的方法是 Service Broker。查找“Service Broker 内部激活”。实际上,正确设置它有点复杂,因此您可能会选择使用池选项。

于 2009-04-29T13:46:10.503 回答