Как отключить SCHEMABINDING для вида, не создавая его заново?


Ответы:


11

Да. Хорошо, что вы используете SCHEMABINDING (мы всегда так делаем), и иногда вам приходится удалять его, чтобы изменить зависимый объект. Просто измените вид

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

я тоже, но иногда другие объекты (функции, представления) зависят от этого. Так что будет полезно пометить / снять отметку с этого флага на некоторое время :). Так что это невозможно в текущей версии БД, да?
Гарик

@garik: правильно, у меня та же проблема. Запустите ALTER для каждого зависимого объекта ... В любой момент времени SQL Server будет применять правила: вы не можете "отключить", потому что это приведет к несогласованности
gbn

8

Разве ALTER VIEW не позволит вам сделать это? Когда вы создаете представление, вы делаете:

CREATE VIEW
WITH SCHEMABINDING
AS
SELECT stmt
GO

Итак, потеряем предложение WITH:

ALTER VIEW viewname
AS
SELECT stmt
GO

Смотрите ALTER VIEW на MSDN


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

И поставить СХЕМУ:

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
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.