通过 Management Studio 在脚本中使用 EXISTS 返回错误值
Posted
技术标签:
【中文标题】通过 Management Studio 在脚本中使用 EXISTS 返回错误值【英文标题】:Using EXISTS return wrong values in Script via Management Studio 【发布时间】:2015-06-03 08:11:36 【问题描述】:我对以下查询有疑问。
第 1 部分
更新表格。
第 2 部分
更改列名。
如果我通过 Management Studio 重新运行脚本,我会收到错误,
“permissiontype_id”列不存在。
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
【问题讨论】:
If I rerun the script
: 如果你真的是说rerun
那么它应该会失败,因为该列被重命名为permissiontype
而不是permissiontype_id
.. 脚本第一次运行时没有错误吗?你能告诉我们gptbl_user_permission
的DDL吗?
【参考方案1】:
这个错误是编译时错误,不是因为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
语句将永远不会被编译并且你不会得到错误。
【讨论】:
太棒了。 executeSQL 在这一点上解决了它。现在将用这个重写我的脚本的某些部分。谢谢=) @SteveFörster - 几年前我遇到了同样的问题。IF EXISTS
只能带你走这么远:)以上是关于通过 Management Studio 在脚本中使用 EXISTS 返回错误值的主要内容,如果未能解决你的问题,请参考以下文章
SQL Management Studio Express 在记事本中打开 SQL 脚本
SQL Server Management Studio 2008 Runas 用户在不同的域上通过 ***
SQL Server Management Studio 中的脚本大小限制
SQL Management Studio 在脚本创建后无法识别表存在