如何在不重新创建视图的情况下关闭SCHEMABINDING?


Answers:


11

是。最好使用SCHEMABINDING(我们总是这样做),有时您必须删除它才能更改从属对象。只是改变视图

ALTER VIEW myView
--Remove this WITH SCHEMABINDING
AS
SELECT ...
GO

我也是,但是有时其他对象(功能,视图)也依赖于此。所以最好将这个标志标记/取消标记一段时间:)。因此,在当前版本的db中是不可能的,是吗?
加里克2011年

@garik:是的,我有同样的问题。在每个依赖对象上运行ALTER ...在任何时间点,SQL Server都会强制执行以下规则:您无法“关闭”,因为这会导致不一致
gbn

8

ALTER VIEW不会允许您完成此操作吗?创建视图时,您将执行以下操作:

CREATE VIEW
WITH SCHEMABINDING
AS
SELECT stmt
GO

因此,丢失WITH子句:

ALTER VIEW viewname
AS
SELECT stmt
GO

在MSDN上查看ALTER VIEW


5

看了几个小时后,我为此创建了2个存储过程。希望这可以帮助某人

CREATE PROCEDURE ViewRemoveSchemaBinding
    @ViewName VARCHAR(MAX)
AS
BEGIN
    DECLARE @PositionShemaBinding INT
    DECLARE @Command NVARCHAR(MAX)

    SELECT @Command = OBJECT_DEFINITION(OBJECT_ID(@ViewName));
    SET @PositionShemaBinding = CHARINDEX('WITH SCHEMABINDING', @Command)

    IF NOT @PositionShemaBinding = 0 BEGIN
        -- WITH SCHEMA BINDING IS PRESENT... Let's remove it !
        SET @Command = STUFF(@Command, CHARINDEX('WITH SCHEMABINDING', @Command), LEN('WITH SCHEMABINDING'), '');
        SET @Command = REPLACE(@Command, 'CREATE VIEW', 'ALTER VIEW');

        EXECUTE sp_executesql @Command
    END
END

并放入SCHEMABINDING:

CREATE PROCEDURE ViewAddSchemaBinding
    @ViewName VARCHAR(MAX)
AS
BEGIN
    DECLARE @PositionShemaBinding INT
    DECLARE @Command NVARCHAR(MAX)
    DECLARE @ObjectName VARCHAR(MAX)

    SELECT  @Command = OBJECT_DEFINITION(OBJECT_ID(@ViewName)),
            @ObjectName = OBJECT_NAME(OBJECT_ID(@ViewName));

    SET @PositionShemaBinding = PATINDEX('%WITH SCHEMABINDING%', @Command)

    IF @PositionShemaBinding = 0 BEGIN
        -- WITH SCHEMA BINDING IS NOT PRESENT... Let's add it !
        SET @Command = REPLACE(@Command, 'CREATE VIEW', 'ALTER VIEW');

        -- IF OBJECT NAME IS INTO BRAKETS, We need to handle it
       IF NOT CHARINDEX('[' + @ObjectName + ']', @Command) = 0 BEGIN
           SET @ObjectName = '[' + @ObjectName + ']'
       END

       SET @Command = STUFF(@Command, CHARINDEX(@ObjectName, @Command), LEN(@ObjectName), @ObjectName + ' WITH SCHEMABINDING ');

        EXECUTE sp_executesql @Command
    END
END

按“原样”提供...


2

即使此视图自创建以来已被重命名,该版本的ViewRemoveSchemaBinding仍然有效。(问题是,如果视图已重命名,则OBJECT_DEFINITION()仍将使用旧名称返回定义。)

CREATE PROCEDURE [dbo].[ViewRemoveSchemaBinding]
    @ViewName VARCHAR(MAX)
AS
BEGIN
    DECLARE @PositionShemaBinding INT
    DECLARE @Command NVARCHAR(MAX)

    SELECT @Command = OBJECT_DEFINITION(OBJECT_ID(@ViewName));
    SET @PositionShemaBinding = CHARINDEX('WITH SCHEMABINDING', @Command)

    IF NOT @PositionShemaBinding = 0 BEGIN
        SET @Command = 'ALTER VIEW ' + @ViewName + ' ' + RIGHT(@Command, LEN(@Command) - @PositionShemaBinding + 1);

        EXECUTE sp_executesql @Command
    END
END

似乎在运行此命令后,重命名问题消失了,因此不需要更改ViewAddSchemaBinding。


1
这行不通,因为该命令仍然包含“ WITH SCHEMABINDING”-要对其进行修复,请将其用法更改RIGHT为:RIGHT(@Command, LEN(@Command) - (@PositionShemaBinding + LEN('WITH SCHEMABINDING')))
Cocowalla
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.