Как проверить, успешно ли выполнено 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;
Другие вопросы по тегам