使用EXISTS通过Management Studio

时间:2015-06-03 08:11:37

标签: sql-server sql-server-2008 ssms exists

我对以下查询有疑问。

第1部分

更新表格。

第2部分

更改列名。

如果我通过Management Studio重新运行脚本,则会出现错误,

  

列“permissiontype_id”不存在。

存在中的选择语句显示正确的结果......

我的脚本中出现了一些错误,需要摆脱它们......

第一声明

IF EXISTS (
    SELECT 1
    FROM sys.columns
    WHERE NAME = N'permissiontype_id'
        AND Object_ID = Object_ID(N'[dbo].[gptbl_user_permission]')
    )
BEGIN
UPDATE gptbl_user_permission
SET permissiontype_id = 1
WHERE objecttype_id = 'resultinfo'
END
GO

第二声明

IF EXISTS (
    SELECT *
    FROM sys.columns
    WHERE NAME = N'permissiontype_id'
        AND Object_ID = Object_ID(N'[dbo].[gptbl_user_permission]')
    )
BEGIN
ALTER TABLE [dbo].[gptbl_user_permission]

DROP CONSTRAINT PK_gptbl_user_permission

EXEC sp_rename '[dbo].[gptbl_user_permission].[permissiontype_id]'
    , 'permissiontype'
    , 'COLUMN';

ALTER TABLE [dbo].[gptbl_user_permission] ADD CONSTRAINT PK_gptbl_user_permission PRIMARY KEY CLUSTERED (
    [objecttype_id] ASC
    , [permissiontype] ASC
    , [user_id] ASC
    )
    WITH (
            PAD_INDEX = OFF
            , STATISTICS_NORECOMPUTE = OFF
            , IGNORE_DUP_KEY = OFF
            , ALLOW_ROW_LOCKS = ON
            , ALLOW_PAGE_LOCKS = ON
            )
END
GO

1 个答案:

答案 0 :(得分:0)

此错误是编译时错误,而不是因为EXISTS。如果您在第二次运行后运行EXISTS查询,则不会返回任何内容

SELECT 1
FROM sys.columns
WHERE NAME = N'permissiontype_id'
    AND Object_ID = Object_ID(N'[dbo].[gptbl_user_permission]')

因此,在运行时,控件在第一次运行后永远不会到达UPDATE

UPDATE gptbl_user_permission
SET permissiontype_id = 1
WHERE objecttype_id = 'resultinfo'

您收到此错误的原因是因为在初始运行之后,SQL Server会检查查询的语法,此查询中涉及的表和列。此时,SQL Server知道没有列permissiontype_id并引发错误。

<强>解决方案

由于此错误是由编译引起的,因此您可以使用动态sql强制在UPDATE的运行时进行编译,如下所示:

IF EXISTS (
    SELECT 1
    FROM sys.columns
    WHERE NAME = N'permissiontype_id'
        AND Object_ID = Object_ID(N'[dbo].[gptbl_user_permission]')
    )
BEGIN
EXEC sp_executeSQL N'
UPDATE gptbl_user_permission
SET permissiontype_id = 1
WHERE objecttype_id = ''resultinfo'''
END
GO

由于EXISTS每次首次运行后都会返回false,因此动态UPDATE语句永远不会被编译,您也不会收到错误。