Почему этот TSQL терпит неудачу? - PullRequest
2 голосов
/ 31 октября 2011
IF NOT EXISTS(SELECT * FROM SYS.COLUMNS WHERE Name=N'isHidden' AND Object_ID=Object_ID(N'Templates'))
BEGIN
    BEGIN TRANSACTION
    GO
        CREATE TABLE dbo.Tmp_Templates
            (
            ID int NOT NULL IDENTITY (1, 1),
            isHidden bit NULL,
            FileName nvarchar(255) NOT NULL,
            Name nvarchar(255) NOT NULL,
            Description nvarchar(1024) NULL,
            UploadedByTVDBUsersID int NOT NULL,
            Created datetime NOT NULL
            )
        GO
        SET IDENTITY_INSERT dbo.Tmp_Templates ON
        GO
        IF EXISTS(SELECT * FROM dbo.Templates)
             EXEC('INSERT INTO dbo.Tmp_Templates (ID, FileName, Name, Description, UploadedByTVDBUsersID, Created)
                SELECT ID, FileName, Name, Description, UploadedByTVDBUsersID, Created FROM dbo.Templates WITH (HOLDLOCK TABLOCKX)')
        GO
        SET IDENTITY_INSERT dbo.Tmp_Templates OFF
        GO
        DROP TABLE dbo.Templates
        GO
        EXECUTE sp_rename N'dbo.Tmp_Templates', N'Templates', 'OBJECT' 
        GO
        ALTER TABLE dbo.Templates ADD CONSTRAINT
            PK__Templates__499219E9 PRIMARY KEY CLUSTERED 
            (
            ID
            )
        GO
        PRINT N'  Templates ADD isHidden'
    COMMIT
END

Приводит к ошибке:

Сообщение 102, Уровень 15, Состояние 1, Строка 7 Неверный синтаксис рядом с «СДЕЛКА».Внимание! Изменение любой части имени объекта может привести к поломке сценариев и хранимых процедур.

Обновление:
Без учета оператора IF, обертывающего транзакцию, этот SQL генерируется Microsoft SQLServer Management Studio.

Если я удаляю оператор переноса IF, тогда все работает, но мне нужно, чтобы изменение произошло только в том случае, если поле еще не существует.Как я могу заставить заявление IF работать должным образом?

Хм ... почему -1 и голосование закрываются?

Ответы [ 3 ]

2 голосов
/ 31 октября 2011

Мне пришлось заключить каждую часть транзакции в оператор IF, чтобы GO не были встроены в оператор IF.Следующий TSQL работает просто отлично.Транзакция обновляет схему должным образом.

BEGIN TRANSACTION
GO
    IF NOT EXISTS(SELECT * FROM SYS.COLUMNS WHERE Name=N'isHidden' AND Object_ID=Object_ID(N'Templates'))
    BEGIN
        CREATE TABLE dbo.Tmp_Templates
            (
            ID int NOT NULL IDENTITY (1, 1),
            isHidden bit NULL,
            FileName nvarchar(255) NOT NULL,
            Name nvarchar(255) NOT NULL,
            Description nvarchar(1024) NULL,
            UploadedByTVDBUsersID int NOT NULL,
            Created datetime NOT NULL
            )
        ALTER TABLE dbo.Tmp_Templates ADD PRIMARY KEY (ID)
    END
    GO
    IF NOT EXISTS(SELECT * FROM SYS.COLUMNS WHERE Name=N'isHidden' AND Object_ID=Object_ID(N'Templates'))
    BEGIN
        SET IDENTITY_INSERT dbo.Tmp_Templates ON
    END
    GO
    IF NOT EXISTS(SELECT * FROM SYS.COLUMNS WHERE Name=N'isHidden' AND Object_ID=Object_ID(N'Templates'))
    BEGIN
        IF EXISTS(SELECT * FROM dbo.Templates)
             EXEC('INSERT INTO dbo.Tmp_Templates (ID, FileName, Name, Description, UploadedByTVDBUsersID, Created)
                SELECT ID, FileName, Name, Description, UploadedByTVDBUsersID, Created FROM dbo.Templates WITH (HOLDLOCK TABLOCKX)')
    END
    GO
    IF NOT EXISTS(SELECT * FROM SYS.COLUMNS WHERE Name=N'isHidden' AND Object_ID=Object_ID(N'Templates'))
    BEGIN
        SET IDENTITY_INSERT dbo.Tmp_Templates OFF
    END
    GO
    IF NOT EXISTS(SELECT * FROM SYS.COLUMNS WHERE Name=N'isHidden' AND Object_ID=Object_ID(N'Templates'))
    BEGIN
        DROP TABLE dbo.Templates
    END
    GO
    IF NOT EXISTS(SELECT * FROM SYS.COLUMNS WHERE Name=N'isHidden' AND Object_ID=Object_ID(N'Templates'))
    BEGIN
        EXECUTE sp_rename N'dbo.Tmp_Templates', N'Templates', 'OBJECT' 
        PRINT N'  Templates ADD isHidden'
    END
    GO
COMMIT
0 голосов
/ 31 октября 2011

первый оператор GO разделил ваш запрос на

IF NOT EXISTS(SELECT * FROM SYS.COLUMNS WHERE Name=N'isHidden' AND Object_ID=Object_ID(N'Templates'))
BEGIN
    BEGIN TRANSACTION
    //error - END missing

И есть ключевое слово BEGIN без END.Вам необходимо удалить оператор GO.

ОБНОВЛЕНИЕ:

IF 1 = 1
BEGIN
    SELECT * FROM someTable
    GO
END

также сгенерировать Msg 102, уровень 15, состояние 1, строка 3 Неверный синтаксис рядом с 'someTable.

0 голосов
/ 31 октября 2011

SqlServer не позволит вам использовать sp_rename внутри транзакции, так как это может сильно испортить ситуацию.

Вы можете удалить и добавить таблицу снова, в вашем случае вы также можете использовать временную таблицу для выполнения запроса, усечения старой таблицы и перемещения строк из temp в Templates.

Sample temp table
CREATE TABLE #myTempTable
(
  DummyField1 INT,
  DummyField2 VARCHAR(20)
)

Ссылка http://msdn.microsoft.com/en-us/library/ms188351.aspx

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...