Como desligo o SCHEMABINDING para uma visualização sem recriá-la?

Respostas:

11

Sim. É bom que você use SCHEMABINDING (sempre usamos) e, às vezes, você precisa removê-lo para alterar um objeto dependente. Apenas alterar a vista

ALTER VIEW myView
--Remove this WITH SCHEMABINDING
AS
SELECT ...
GO
gbn
fonte
eu também, mas às vezes outros objetos (funções, visualizações) dependem desse. Portanto, será bom marcar / desmarcar esse sinalizador por um tempo :). Portanto, é impossível na versão atual do db, sim?
Garik
@garik: correto, tenho o mesmo problema. Run ALTER em cada objeto dependente ... Em qualquer ponto no tempo SQL Server irá cumprir as regras: você não pode "desligar", porque isso levaria a inconsistência
GBN
8

O ALTER VIEW não permitirá que você faça isso? Ao criar uma exibição, você faria:

CREATE VIEW
WITH SCHEMABINDING
AS
SELECT stmt
GO

então, perca a cláusula WITH:

ALTER VIEW viewname
AS
SELECT stmt
GO

Consulte ALTER VIEW no MSDN

SQLRockstar
fonte
5

Depois de procurar por horas, criei 2 proc armazenados para isso. Espero que isso ajude alguém

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 para colocar o 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

É fornecido "como está" ...

boblemar
fonte
2

Esta versão do ViewRemoveSchemaBinding funciona mesmo que a exibição tenha sido renomeada desde que foi criada. (O problema é que, se a exibição foi renomeada, OBJECT_DEFINITION () ainda retornará uma definição usando o nome antigo.)

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

Parece que, após a execução, o problema de renomeação desaparece e, portanto, o ViewAddSchemaBinding não precisa ser alterado ....

David Roodman
fonte
11
Isso não funciona, pois o comando ainda contém 'WITH SCHEMABINDING' - para corrigi-lo, altere o uso de RIGHTpara:RIGHT(@Command, LEN(@Command) - (@PositionShemaBinding + LEN('WITH SCHEMABINDING')))
Cocowalla