更改现有 VIEW 的 SCHEMABINDING

Mic*_*142 5 t-sql sql-server sql-server-data-tools

我有一个现有的数据库(SSDT 项目作为源),我必须在其中更新表。我只是将列类型从 更改nvarchar(MAX)nvachar(256)。问题是,我有一个现有视图绑定到该表SCHEMABINDING。我无法编辑表列,因为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
Run Code Online (Sandbox Code Playgroud)

Aar*_*and 8

没有命令可以禁用WITH SCHEMABINDING。您可以通过删除视图并在没有选项的情况下重新创建它,或者简单地更改它来完成此操作。在你的情况下:

ALTER VIEW [base].[VIEW_DEPENDING_ON_TABLE]
-- WITH SCHEMABINDING
AS
    SELECT ...;
Run Code Online (Sandbox Code Playgroud)

对基础表进行更改后,您可以再次更改视图:

ALTER VIEW [base].[VIEW_DEPENDING_ON_TABLE]
WITH SCHEMABINDING
AS
    SELECT ...;
Run Code Online (Sandbox Code Playgroud)

手边没有脚本吗?没关系,您可以将其从 中拉出sys.sql_modules,但需要进行一些操作才能从 转换CREATEALTER并删除WITH SCHEMABINDING。您可以编写解析它的代码,但这非常脆弱,因为替换或注释短语“使用模式绑定”可能非常困难 - 它可能有多个空格、制表符、回车符、非打印字符等,它也可以存在于代码的其他部分(例如注释,甚至作为表或列别名)。

  • @Ben我试图在上面的评论中推动简单的手动调整,但是当他们在`sys.sql_modules`中找到定义时,OP似乎欣喜若狂,所以`´\_(ツ)_/´`... (2认同)