通过 Management Studio 在脚本中使用 EXISTS return 错误值

Using EXISTS return wrong values in Script via Management Studio

我遇到以下查询的问题。

第 1 部分

更新 table。

第 2 部分

更改列名。

如果我通过 Management Studio 重新运行脚本,我会收到错误,

The column "permissiontype_id" does not exist.

Exists 中的 Select 语句显示正确的结果...

我的脚本中的某些语句出现此类错误,需要删除它们...

第一个声明

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

此错误是编译时错误,不是因为 EXISTS。如果你 运行 你的 EXISTS 查询在第二个 运行 之后,它不会 return 任何东西

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 服务器检查查询的语法后,table 和此查询中涉及的列。此时 SQL 服务器知道没有列 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 每次在第一个 运行 之后都会 return false,因此动态 UPDATE 语句永远不会被编译,你也不会得到错误.