Как проверить, успешно ли выполнено sp_rename?
Я выполняю следующий запрос:
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, чтобы обеспечить безопасность и надежность процесса (на случай, если какой-либо шаг завершится неудачей). Может ли кто-нибудь помочь с этим? Заранее спасибо.
2 ответа
Вы можете использовать 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
не заставит вас потерять содержимое таблицы, он просто изменит имя ссылки на таблицу и обновит все ее ограничения и ссылки на индексы. Это также вызовет ошибку, если таблица для переименования не существует. Возможно, вы хотите заключить процесс в транзакцию и выполнить откат, если что-то не получится.
РЕДАКТИРОВАТЬ:
Для базовой обработки транзакций вы можете использовать следующее. Пожалуйста, прочитайте документацию по использованию транзакции, чтобы узнать, как она работает правильно, может потребоваться некоторое время.
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
чтобы отменить ваши изменения.
EXEC sp_rename "dbo.2015_10_2_cs", "dbo.2015_10_2"
Это не будет делать то, что вы ожидаете. Новая таблица будет иметь имя [dbo].[Dbo.2015_10_2], если вы укажете имя схемы в имени новой таблицы. Переименованные таблицы неявно присутствуют в схеме существующей таблицы, так как нужно использовать ALTER SCHEMA
вместо sp_rename
перемещать объект между схемами.
Есть ряд других проблем с вашим скриптом. Поскольку имя таблицы начинается с цифры, оно не соответствует правилам именования обычных идентификаторов и должно быть заключено в квадратные скобки или двойные кавычки. Литеральные параметры передаются 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;