这个:
use test;
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
BEGIN TRANSACTION;
EXEC sp_RENAME 'table1.asd' , 'ads', 'COLUMN';
INSERT INTO table1 (ads) VALUES (12);
COMMIT
是一个简单的示例,它演示了我想做什么。
我想以某种方式更改表并在一个事务中执行插入/删除(或对表进行其他修改)。
问题是 sp_RENAME
的结果永远不会立即对 INSERT
语句可见。我玩过不同的事务隔离级别 - 它总是相同的(因此事务永远不会提交)。
通常我只会使用 GO 语句将其分批处理,但我需要将其分批处理,因为...
我的真正任务是编写一个脚本,将身份和 FK 添加到表中(这需要使用新模式创建另一个表,从旧表执行身份插入,重命名表并应用约束)。我需要谨慎行事——如果程序的任何部分失败,我必须回滚整个事务。这就是为什么我想做这样的事情:
BEGIN TRAN
--some statement
IF (@@ERROR <> 0) GOTO ERR_HANDLER
-- some other statement
IF (@@ERROR <> 0) GOTO ERR_HANDLER
COMMIT TRAN
RETURN 0
ERR_HANDLER:
PRINT 'Unexpected error occurred!'
ROLLBACK TRAN
RETURN 1
由于标签只能在批处理中使用,所以我不能使用 GO 语句。
那么我怎样才能:
- 使语句(即 ALTER TABLE、sp_RENAME)立即生效?
或
- 以其他方式编写整个解决方案,以便在生产数据库中安全运行?
最佳答案
问题是批处理在遇到对重命名列的引用时会失败,因此整个批处理永远不会执行 - 并不是事务的影响不可见。
您可以将引用列新名称的语句放在 EXEC('')
block 中,以将编译推迟到列重命名之后。
EXEC sp_rename 'table1.asd' , 'ads', 'COLUMN';
EXEC('INSERT INTO table1 (ads) VALUES (12);')
关于sql-server - SQL Server - 事务中一个语句的结果立即对下一个语句可见?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8562059/