我创建了一个批处理文件来运行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工作正常)。我当然可以编写一个轮询过程来查看一些表和拾取事件,但我更喜欢这是触发器,使其不那么复杂(或者我正在做相反的事情:))。
有帮助吗?

解决方案

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

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top