Jak wyłączyć SCHEMABINDING dla widoku bez jego odtwarzania?

Odpowiedzi:

11

Tak. Dobrze, że używasz SCHEMABINDINGU (zawsze tak robimy), a czasem musisz go usunąć, aby zmienić zależny obiekt. Wystarczy zmienić widok

ALTER VIEW myView
--Remove this WITH SCHEMABINDING
AS
SELECT ...
GO
gbn
źródło
ja też, ale czasami inne obiekty (funkcje, widoki) zależą od tego. Dobrze będzie na chwilę zaznaczyć / odznaczyć tę flagę :). W obecnej wersji db jest to niemożliwe, tak?
garik
@garik: poprawnie, mam ten sam problem. Uruchom ALTER na każdym obiekcie zależnym ... W dowolnym momencie SQL Server będzie egzekwować reguły: nie możesz „wyłączyć”, ponieważ prowadziłoby to do niespójności
gbn
8

Czy ALTER VIEW nie pozwoli ci tego zrobić? Kiedy tworzysz widok, robisz:

CREATE VIEW
WITH SCHEMABINDING
AS
SELECT stmt
GO

więc zgub klauzulę WITH:

ALTER VIEW viewname
AS
SELECT stmt
GO

Zobacz ALTER VIEW na MSDN

SQLRockstar
źródło
5

Po rozglądaniu się godzinami, stworzyłem do tego 2 przechowywane procy. Mam nadzieję, że to komuś pomoże

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

I umieścić 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

Jest dostarczany „tak jak jest” ...

boblemar
źródło
2

Ta wersja ViewRemoveSchemaBinding działa, nawet jeśli nazwa widoku została zmieniona od czasu jego utworzenia. (Problem polega na tym, że jeśli zmieniono nazwę widoku, OBJECT_DEFINITION () nadal zwróci definicję przy użyciu starej nazwy).

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

Wygląda na to, że po uruchomieniu tego problemu zmiana nazwy znika, więc ViewAddSchemaBinding nie musi być zmieniany ...

David Roodman
źródło
1
To nie działa, ponieważ polecenie nadal zawiera „Z SCHEMABINDINGIEM” - aby to naprawić, zmień użycie RIGHTna:RIGHT(@Command, LEN(@Command) - (@PositionShemaBinding + LEN('WITH SCHEMABINDING')))
Cocowalla