¿Cómo desactivo SCHEMABINDING para una vista sin volver a crearla?

Respuestas:

11

Sí. Es bueno que use SCHEMABINDING (siempre lo hacemos) y, a veces, debe eliminarlo para cambiar un objeto dependiente. Solo ALTERA la vista

ALTER VIEW myView
--Remove this WITH SCHEMABINDING
AS
SELECT ...
GO
gbn
fuente
yo también, pero a veces otros objetos (funciones, vistas) dependen de este. Por lo tanto, será bueno marcar / desmarcar esta bandera por un tiempo :). Entonces, es imposible en la versión actual de db, ¿sí?
garik
@garik: correcto, tengo el mismo problema. Ejecute ALTER en cada objeto dependiente ... En cualquier momento, SQL Server aplicará las reglas: no puede "apagarse" porque esto generaría inconsistencias
gbn
8

¿ALTER VIEW no le permitirá hacer esto? Cuando crea una vista que haría:

CREATE VIEW
WITH SCHEMABINDING
AS
SELECT stmt
GO

entonces, pierda la cláusula WITH:

ALTER VIEW viewname
AS
SELECT stmt
GO

Ver ALTER VIEW en MSDN

SQLRockstar
fuente
5

Después de mirar durante horas, creé 2 procesos almacenados para esto. Espero que esto ayude a alguien

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

Y para poner el 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

Se proporciona "tal cual" ...

boblemar
fuente
2

Esta versión de ViewRemoveSchemaBinding funciona incluso si la vista ha cambiado de nombre desde que se creó. (El problema es que si la vista ha cambiado de nombre, OBJECT_DEFINITION () aún devolverá una definición con el nombre anterior).

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 después de ejecutar esto, el problema de cambio de nombre desaparece, por lo que ViewAddSchemaBinding no necesita ser alterado ...

David Roodman
fuente
1
Esto no funciona, ya que el comando todavía contiene 'WITH SCHEMABINDING' - para solucionarlo, cambie el uso de RIGHTa:RIGHT(@Command, LEN(@Command) - (@PositionShemaBinding + LEN('WITH SCHEMABINDING')))
Cocowalla