Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 在事务中执行语句,而不将其登记到该事务中_Sql Server_Tsql_Transactions_Sql Server 2017 - Fatal编程技术网

Sql server 在事务中执行语句,而不将其登记到该事务中

Sql server 在事务中执行语句,而不将其登记到该事务中,sql-server,tsql,transactions,sql-server-2017,Sql Server,Tsql,Transactions,Sql Server 2017,我在批处理中有一些SQL语句,我想对它们进行性能分析。为此,我创建了一个记录执行时间的存储过程 但是,我还希望能够回滚主批处理执行的更改,同时仍然保留性能日志 另一种方法是运行批处理,将性能数据复制到另一个数据库,从备份中恢复数据库,重新应用我要分析的所有更改,以及其他更改,然后重新开始。这比不包括登录事务的行为更耗时 我们可以这样说: BEGIN TRANSACTION SET @StartTime = SYSDATETIME -- Do stuff here UPDATE ABC SET x

我在批处理中有一些SQL语句,我想对它们进行性能分析。为此,我创建了一个记录执行时间的存储过程

但是,我还希望能够回滚主批处理执行的更改,同时仍然保留性能日志

另一种方法是运行批处理,将性能数据复制到另一个数据库,从备份中恢复数据库,重新应用我要分析的所有更改,以及其他更改,然后重新开始。这比不包括登录事务的行为更耗时

我们可以这样说:

BEGIN TRANSACTION
SET @StartTime = SYSDATETIME
-- Do stuff here
UPDATE ABC SET x = fn_LongRunningFunction(x)
EXECUTE usp_Log 'Do stuff', @StartTime
SET @StartTime = SYSDATETIME
-- Do more stuff here
EXEC usp_LongRunningSproc()
EXECUTE usp_Log 'Do more stuff', @StartTime
ROLLBACK
如何将
usp_Log
保存到表中的结果持久化,而不将其与事务中其他地方发生的更改一起回滚

在我看来,理想情况下,
usp_Log
不会以某种方式将自己登记到可能回滚的事务中

我正在寻找一种能够以最可靠的方式实现的解决方案,尽可能减少编码或工作,并且对所分析脚本的性能影响最小

编辑


正在分析的脚本非常耗时—从一小时到几天—我需要能够在事务完成或回滚之前看到中间分析结果。在查看日志之前,我不能等待批处理结束。

您可以使用表变量进行此操作。与普通变量一样,表变量不受
回滚的影响。在所有
COMMIT
ROLLBACK
语句之后,您需要将性能日志数据插入到一个表变量中,然后在过程结束时将其插入到一个普通表中。

这听起来可能有点过火(鉴于目的),但您可以创建一个CLR存储过程来接管进度日志记录,并在其中打开一个单独的连接以写入日志数据

通常,建议尽可能在CLR对象中使用,因为它简化了许多事情。然而,在您的特定情况下,您希望从上下文中分离出来(特别是从当前事务中),因此常规连接是一种方法


注意:如果您以前从未涉足过SQL Server中的CLR编程,您可能会发现学习曲线有点陡峭。这一点,以及使其正常工作所需的服务器重新配置量(SQL server实例和底层操作系统)似乎也非常昂贵,不值得这么麻烦。尽管如此,我还是认为这是一种可行的方法。

< P> >,正如罗杰提到的,SqLCR是一种选择。但是,因为SQLCLR是不允许的,所以您就不走运了

在SQL Server 2017中,还有另一个选项,即使用SQL Server可扩展性框架和对Python的支持


您可以使用它生成Python代码,该代码将调用回SQL Server实例并执行
usp\u log
过程。

另一个相当模糊的选项是将其他会话绑定到长时间运行的事务以进行监视

在事务开始时调用并显示绑定令牌

然后在另一个会话调用中,您可以检查事务的中间状态

或者您可以使用(NOLOCK)读取日志

或者,您可以使用将调试消息发送到客户端并将其镜像到SQL日志

或者您可以在SQL跟踪或XEvents中使用和监视它们


或者您可以使用配置为不传播事务的。

对不起,我忘了提到我需要能够在执行期间查看日志条目。将日志项存储在表变量中不会有帮助,因为批处理可能需要四天时间,我需要更快的分析结果。您可以同时将数据写入表变量和普通表,然后,如果有回滚,将变量中的记录复制到表中,以替换已回滚的记录。这并不漂亮,但它会起作用。更改
事务隔离级别如何。这可能吗?我不这么认为,这与当事务内部的语句和事务外部的语句都影响相同的数据时,它们是如何相互作用的有关,但这并不影响事务完成时发生的事情。只是澄清一下:
事务隔离级别
在这里不会影响任何事情,也就是说,不可能。通常,是的。。。但不幸的是,在这种环境中不允许使用SQLCLR。