gpt4 book ai didi

sql - 我们可以在 SQL 事务中多次使用 'GO' 吗?

转载 作者:行者123 更新时间:2023-12-02 04:47:43 25 4
gpt4 key购买 nike

我们可以在 SQL 事务 中多次使用 GO 语句吗?我有一个很长的 T-SQL 脚本,我想在 SQL 事务 中运行它。如果一切顺利那么我将提交,否则将回滚。

但是,在运行该查询时,我收到了错误,例如“创建函数必须是批处理中的唯一语句”。当我在其中创建和删除许多函数和过程时。

我没有在脚本中的任何地方使用GO。我的问题是 - 我可以在那个长脚本中使用多次 GO 语句吗?因为,GO创建了一个批处理,如果批处理第一次执行成功但下次失败,那么rollback transaction语句是否能够真正回滚已执行的事务?

我的脚本结构如下:

PRINT 'Transaction Started'
BEGIN TRY
BEGIN TRAN

Drop Function
....
....
Create Function
....
....
Drop Procedure
....
....
Lots of statements
....
....

COMMIT TRAN
PRINT 'Transaction Succeeded'
END TRY
BEGIN CATCH
PRINT 'Transaction Failed'
IF(@@TRANCOUNT > 0)
ROLLBACK TRAN
END CATCH

我正在创建此脚本,以便在单个脚本中将一些更改从 newDB 迁移到 oldDB。

最佳答案

你正在混淆概念。 GO 不是 Transact-SQL 概念,不是该语言的一部分,也不被 SQL Server 理解。 GO 是工具批处理分隔符。默认情况下,sqlcmd.exe 和 SSMS 都使用 GO 作为批处理分隔符。批处理分隔符用于标识 SQL 源文件中的各个批处理。客户端工具一次向服务器发送一批(当然,省略分隔符)。

交易可以跨批处理。 TRY/CATCH block 不能。 CREATE/ALTER 语句必须是批处理中的唯一语句(注释不是语句,函数过程体中包含的语句才是包含的)。

类似于您想要做的事情可以通过启动事务并在第一个错误时中止执行来实现(-b at sqlcmd.exe start,或使用:on error exit in SSMS)。

但是在长事务中执行 DDL 是行不通的。特别是如果您打算将其与 DML 混合使用。我必须调查的大多数损坏都来自这种组合(Xact、DDL + DML、回滚)。我强烈建议不要这样做。

安全部署架构更新的唯一方法是进行备份、部署,并在出现问题时从备份中恢复。

请注意,Dan 推荐的(动态 SQL)之所以有效,是因为 sp_executesql 启动了一个新的内部批处理。该批处理将满足 CREATE/ALTER 限制。

关于sql - 我们可以在 SQL 事务中多次使用 'GO' 吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34178270/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com