更改现有 VIEW 的 SCHEMABINDING
Change SCHEMABINDING for existing VIEW
我有一个现有的数据库(SSDT 项目作为源),我必须在其中更新一个 table。我只是将列类型从 nvarchar(MAX)
更改为 nvachar(256)
。问题是,我有一个现有视图绑定到 table 和 SCHEMABINDING
。我无法编辑 table 列,因为 SCHEMABINDING
阻止影响视图的更改。
在 PreDeploymentScript 中执行以下脚本。当我调用 DROP VIEW [base].[VIEW_DEPENDING_ON_TABLE]
语句时,视图在部署后丢失。我的想法是,在部署期间禁用 SCHEMABINDING
并在完成后启用它。这在 TSQL 脚本中怎么可能?或者有更好的方法吗?
IF EXISTS ( SELECT DATA_TYPE FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = N'base'
AND TABLE_NAME = 'TABLENAME'
AND COLUMN_NAME = 'Instance'
AND CHARACTER_MAXIMUM_LENGTH = -1)
AND NOT EXISTS (SELECT * FROM sys.indexes WHERE name='IX_TABLENAME_Instance' AND object_id = OBJECT_ID(N'[base].[TABLENAME]'))
BEGIN
IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[base].[VIEW_DEPENDING_ON_TABLE]') AND type in (N'V'))
BEGIN
DROP VIEW [base].[VIEW_DEPENDING_ON_TABLE]
END
IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[base].[TABLENAME]') AND type in (N'U'))
BEGIN
UPDATE [base].[TABLENAME] SET [Instance] = LEFT(Instance, 256)
ALTER TABLE [base].[TABLENAME] ALTER COLUMN [Instance] NVARCHAR(256)
END
IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[base].[TABLENAME]') AND type in (N'U'))
BEGIN
CREATE NONCLUSTERED INDEX [IX_TABLENAME_Instance] ON [base].[TABLENAME]
(
[Instance] ASC
) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
END
END
GO
没有禁用 WITH SCHEMABINDING
的命令。您可以通过删除视图并在没有选项的情况下重新创建它,或者简单地改变它来做到这一点。你的情况:
ALTER VIEW [base].[VIEW_DEPENDING_ON_TABLE]
-- WITH SCHEMABINDING
AS
SELECT ...;
对底层 table 进行更改后,您可以再次更改视图:
ALTER VIEW [base].[VIEW_DEPENDING_ON_TABLE]
WITH SCHEMABINDING
AS
SELECT ...;
手边没有脚本?没关系,您可以从 sys.sql_modules
中提取它,但需要一些修改才能从 CREATE
转换为 ALTER
并删除 WITH SCHEMABINDING
。您可以编写解析它的代码,但这非常脆弱,因为替换或注释短语 "with schemabinding" 可能非常困难 - 它可能不止一次 space、制表符、回车符 returns 、非打印字符等,它也可以存在于代码的其他部分(如注释,甚至作为 table 或列别名)。
我有一个现有的数据库(SSDT 项目作为源),我必须在其中更新一个 table。我只是将列类型从 nvarchar(MAX)
更改为 nvachar(256)
。问题是,我有一个现有视图绑定到 table 和 SCHEMABINDING
。我无法编辑 table 列,因为 SCHEMABINDING
阻止影响视图的更改。
在 PreDeploymentScript 中执行以下脚本。当我调用 DROP VIEW [base].[VIEW_DEPENDING_ON_TABLE]
语句时,视图在部署后丢失。我的想法是,在部署期间禁用 SCHEMABINDING
并在完成后启用它。这在 TSQL 脚本中怎么可能?或者有更好的方法吗?
IF EXISTS ( SELECT DATA_TYPE FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = N'base'
AND TABLE_NAME = 'TABLENAME'
AND COLUMN_NAME = 'Instance'
AND CHARACTER_MAXIMUM_LENGTH = -1)
AND NOT EXISTS (SELECT * FROM sys.indexes WHERE name='IX_TABLENAME_Instance' AND object_id = OBJECT_ID(N'[base].[TABLENAME]'))
BEGIN
IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[base].[VIEW_DEPENDING_ON_TABLE]') AND type in (N'V'))
BEGIN
DROP VIEW [base].[VIEW_DEPENDING_ON_TABLE]
END
IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[base].[TABLENAME]') AND type in (N'U'))
BEGIN
UPDATE [base].[TABLENAME] SET [Instance] = LEFT(Instance, 256)
ALTER TABLE [base].[TABLENAME] ALTER COLUMN [Instance] NVARCHAR(256)
END
IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[base].[TABLENAME]') AND type in (N'U'))
BEGIN
CREATE NONCLUSTERED INDEX [IX_TABLENAME_Instance] ON [base].[TABLENAME]
(
[Instance] ASC
) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
END
END
GO
没有禁用 WITH SCHEMABINDING
的命令。您可以通过删除视图并在没有选项的情况下重新创建它,或者简单地改变它来做到这一点。你的情况:
ALTER VIEW [base].[VIEW_DEPENDING_ON_TABLE]
-- WITH SCHEMABINDING
AS
SELECT ...;
对底层 table 进行更改后,您可以再次更改视图:
ALTER VIEW [base].[VIEW_DEPENDING_ON_TABLE]
WITH SCHEMABINDING
AS
SELECT ...;
手边没有脚本?没关系,您可以从 sys.sql_modules
中提取它,但需要一些修改才能从 CREATE
转换为 ALTER
并删除 WITH SCHEMABINDING
。您可以编写解析它的代码,但这非常脆弱,因为替换或注释短语 "with schemabinding" 可能非常困难 - 它可能不止一次 space、制表符、回车符 returns 、非打印字符等,它也可以存在于代码的其他部分(如注释,甚至作为 table 或列别名)。