为什么这个TSQL失败了?

时间:2011-10-31 19:05:25

标签: tsql

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

导致错误:

  

Msg 102,Level 15,State 1,Line 7语法不正确   '交易'。警告:更改对象名称的任何部分都可以   打破脚本和存储过程。

更新
排除包装事务的IF语句,此SQL由Microsoft SQL Server Management Studio生成。

如果我删除包装IF语句,那么一切正常,但我只需要在字段不存在的情况下进行更改。如何使IF语句正常工作?

嗯......为什么-1和投票结束?

3 个答案:

答案 0 :(得分:2)

我必须在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

答案 1 :(得分:0)

首先将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

还生成消息102,级别15,状态1,行3 'someTable'附近的语法不正确。

答案 2 :(得分:-1)

SqlServer不允许您在事务中使用sp_rename,因为它可能会严重破坏。

您可以再次删除并添加表,在您的情况下,您还可以使用临时表来执行查询工作,截断旧表,并将行从temp移动到模板中。

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

参考 http://msdn.microsoft.com/en-us/library/ms188351.aspx