我正在运行以下查询:
SELECT * INTO dbo.2015_10_2_cs FROM dbo.2015_10_2
IF NOT EXISTS
(SELECT type FROM sys.indexes WHERE object_id = object_id('dbo.2015_10_2_cs')
AND NAME ='cci' AND type = 5)
BEGIN
CREATE CLUSTERED COLUMNSTORE INDEX cci
ON dbo.2015_10_2_cs
DROP TABLE dbo.2015_10_2
EXEC sp_rename "dbo.2015_10_2_cs" , "dbo.2015_10_2"
END
我想确保将表dbo.2015_10_2_cs重命名为dbo.2015_10_2的部分成功完成(不丢失任何数据)。 循环中的步骤应该用SQL事务包围,以保持进程安全可靠(如果任何步骤失败)。 任何人都可以帮忙吗?提前谢谢。
答案 0 :(得分:2)
EXEC sp_rename" dbo.2015_10_2_cs" ," dbo.2015_10_2"
这不符合您的期望。如果在新表名中指定模式名称,则新表将命名为[dbo]。[dbo.2015_10_2]。重命名的表隐含在现有表的模式中,因为必须使用ALTER SCHEMA
而不是sp_rename
来在模式之间移动对象。
您的脚本还有许多其他问题。因为表名以数字开头,所以它不符合regular identifier naming rules,必须用方括号或双引号括起来。传递给sp_rename
的文字参数应该是单引号。您还可以检查存储过程返回代码以确定成功或失败。下面的示例在具有结构化错误处理的事务中执行这些任务。
DECLARE @rc int;
BEGIN TRY
BEGIN TRAN;
IF NOT EXISTS
(SELECT type FROM sys.indexes WHERE object_id = object_id(N'dbo.2015_10_2_cs')
AND NAME ='cci' AND type = 5)
BEGIN
CREATE CLUSTERED COLUMNSTORE INDEX cci
ON dbo.[2015_10_2_cs];
DROP TABLE dbo.[2015_10_2];
EXEC @rc = sp_rename 'dbo.[2015_10_2_cs]' , '2015_10_2';
IF @rc <> 0
BEGIN
RAISERROR('sp_rename returned return code %d',16,1);
END;
END;
COMMIT;
END TRY
BEGIN CATCH
IF @@TRANCOUNT > 0 ROLLBACK;
THROW;
END CATCH;
答案 1 :(得分:1)
您可以使用EXISTS
检查表名和架构。
IF NOT EXISTS (SELECT 'table does not exist' FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = N'2015_10_2'AND TABLE_SCHEMA = 'dbo')
BEGIN
RAISERROR('The table doesn''t exist!!!!', 16, 1)
END
sp_rename
不会让您丢失表内容,它只会更改表引用名称并更新其所有的约束和索引引用。如果要重命名的表不存在,它也会引发错误。也许你想要的是将你的进程包装在一个事务中,如果出现故障就回滚。
修改强>
对于基本事务处理,您可以使用以下内容。请阅读documentation使用交易,可能需要一段时间才能知道它是如何正常工作的。
IF OBJECT_ID('tempdb..#Test') IS NOT NULL
DROP TABLE #Test
CREATE TABLE #Test (Number INT)
SELECT AmountRecords = COUNT(1) FROM #Test -- AmountRecords = 0
BEGIN TRY
BEGIN TRANSACTION
-- Do your statements here
INSERT INTO #Test (Number)
VALUES (1)
DECLARE @errorVariable INT = CONVERT(INT, 'NotAnInteger!!') -- Example of error: can't convert
COMMIT
END TRY
BEGIN CATCH -- If something goes wrong
IF @@TRANCOUNT > 0 -- ... and transaction is still open
ROLLBACK -- Revert statements from the BEGIN TRANSACTION onwards
END CATCH
SELECT AmountRecords = COUNT(1) FROM #Test -- AmountRecords = 0 (the transaction was rolled back and the INSERT reverted)
基本上,您使用BEGIN TRANSACTION
启动还原点,以便在出现故障时返回。一旦您知道一切正常,就使用COMMIT
(从那时起,其他用户将看到更改和修改将被保留)。如果某些内容失败(您需要TRY/CATCH
阻止来处理错误),您可以发出ROLLBACK
来还原您的更改。