Sql server 更改现有视图的SCHEMABINDING
我有一个现有的数据库(SSDT项目作为源),我必须在其中更新一个表。我只是将列类型从Sql server 更改现有视图的SCHEMABINDING,sql-server,tsql,sql-server-data-tools,Sql Server,Tsql,Sql Server Data Tools,我有一个现有的数据库(SSDT项目作为源),我必须在其中更新一个表。我只是将列类型从nvarchar(MAX)更改为nvachar(256)。问题是,我使用SCHEMABINDING将现有视图绑定到此表。我无法编辑表列,因为SCHEMABINDING阻止影响视图的更改 以下脚本在PreDeploymentScript中执行。当我调用DROP VIEW[base].[VIEW\u dependent\u ON\u TABLE]语句时,部署后该视图将丢失。我的想法是,在部署期间禁用SCHEMABIN
nvarchar(MAX)
更改为nvachar(256)
。问题是,我使用SCHEMABINDING
将现有视图绑定到此表。我无法编辑表列,因为SCHEMABINDING
阻止影响视图的更改
以下脚本在PreDeploymentScript中执行。当我调用DROP VIEW[base].[VIEW\u dependent\u ON\u 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
没有命令可以禁用SCHEMABINDING的
。您可以通过删除视图并在没有选项的情况下重新创建它,或者简单地修改它来实现这一点。就你而言:
ALTER VIEW [base].[VIEW_DEPENDING_ON_TABLE]
-- WITH SCHEMABINDING
AS
SELECT ...;
对基础表进行更改后,可以再次更改视图:
ALTER VIEW [base].[VIEW_DEPENDING_ON_TABLE]
WITH SCHEMABINDING
AS
SELECT ...;
手边没有脚本吗?没关系,您可以从sys.sql\u modules
中提取它,但它需要一些处理才能从CREATE
转换为ALTER
,并使用SCHEMABINDING删除。您可以编写解析它的代码,但这是非常脆弱的,因为替换或注释短语“with schemabind”可能非常困难—它可能有不止一次的空格、制表符、回车符、非打印字符等,并且它也可能存在于代码的其他部分(例如注释,甚至作为表或列别名).您不想删除视图,只想删除schemabinding,以便更改表。所以将VIEW dbo.name改为…
,然后进行更改,然后将VIEW dbo.name改为SCHEMABINDING为…
@AaronBertrand好,但是在第一个中将VIEW dbo.name改为…
?如何禁用SCHEMABINDING
?正如我所说,您更改了视图,但忽略了WITH SCHEMABINDING
选项。没有命令将其关闭,您只需更改视图而不打开它。好的,我理解,但是视图定义存储在另一个TSQL脚本中。视图是否已经存在?如果是这样,那么视图定义也存储在sys.sql\u modules
中,因此您可以通过编程方式访问它。但您也可以考虑将视图定义复制到该脚本中,并自行删除Studiabin选项。或者你可以在部署后调用另一个T-SQL脚本。既然sys.SQL_模块中的定义已经以脚本视图的形式写入了,为什么还要在SSMS中调用它呢?@Ben这正是OP想要的。我的回答没有显示来自SSMS的更改,这是我建议的最终结果,无论源代码是来自其他t-SQL脚本、SSMS还是来自元数据。只有从元数据中提取时才需要替换。我假设部署是自动化的,所以这就是为什么…我完全支持自动化。但是,如果成本远远高于收益(这里似乎是对基础表进行一次性修改的情况),我通常会反对。但是我明白你的意思了。@Ben我试图在上面的评论中推动简单的手动调整,但是当他们在sys.sql\u模块
中找到定义时,OP似乎欣喜若狂,所以'\_(ツ)_/“
。。。