Come posso disattivare SCHEMABINDING per una vista senza ricrearla?


Risposte:


11

Sì. È buono che usi SCHEMABINDING (lo facciamo sempre) e talvolta devi rimuoverlo per cambiare un oggetto dipendente. Basta ALTER la vista

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

così ho fatto io, ma a volte altri oggetti (funzioni, viste) dipendono da questo. Quindi sarà bene contrassegnare / deselezionare questa bandiera per un po ':). Quindi è impossibile nell'attuale versione di db, sì?
garik,

@garik: corretto, ho lo stesso problema. Esegui ALTER su ogni oggetto dipendente ... In qualsiasi momento SQL Server imporrà le regole: non è possibile "disattivare" perché ciò comporterebbe incoerenza
gbn

8

ALTER VIEW non ti consentirà di farlo? Quando crei una vista, dovresti:

CREATE VIEW
WITH SCHEMABINDING
AS
SELECT stmt
GO

quindi, perdere la clausola WITH:

ALTER VIEW viewname
AS
SELECT stmt
GO

Vedi ALTER VIEW su MSDN


5

Dopo aver guardato in giro per ore, ho creato 2 proc memorizzati per questo. Spero che questo aiuti qualcuno

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

E per mettere lo 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

Viene fornito "così com'è" ...


2

Questa versione di ViewRemoveSchemaBinding funziona anche se la vista è stata rinominata da quando è stata creata. (Il problema è che se la vista è stata rinominata, OBJECT_DEFINITION () restituirà comunque una definizione usando il vecchio nome.)

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

Sembra che dopo aver eseguito questo il problema di ridenominazione scompaia, quindi ViewAddSchemaBinding non deve essere modificato ....


1
Questo non funziona, poiché il comando contiene ancora 'WITH SCHEMABINDING' - per risolverlo, modifica l'utilizzo di RIGHTin:RIGHT(@Command, LEN(@Command) - (@PositionShemaBinding + LEN('WITH SCHEMABINDING')))
Cocowalla
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.