web-dev-qa-db-fra.com

Comment désactiver SCHEMABINDING pour une vue sans la recréer?

Comment désactiver SCHEMABINDING pour une vue sans la recréer?

22
garik

Oui. C'est bien que vous utilisiez SCHEMABINDING (nous le faisons toujours) et parfois vous devez le supprimer pour changer un objet dépendant. Juste ALTER la vue

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

ALTER VIEW ne vous permettra-t-il pas de faire cela? Lorsque vous créez une vue, vous devez:

CREATE VIEW
WITH SCHEMABINDING
AS
SELECT stmt
GO

donc, perdez la clause WITH:

ALTER VIEW viewname
AS
SELECT stmt
GO

Voir ALTER VIEW sur MSDN

7
SQLRockstar

Après avoir regardé autour pendant des heures, j'ai créé 2 proc stockés pour cela. J'espère que cela aide quelqu'un

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

Et pour mettre le 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

Il est fourni "en l'état" ...

6
boblemar

Cette version de ViewRemoveSchemaBinding fonctionne même si la vue a été renommée depuis sa création. (Le problème est que si la vue a été renommée, OBJECT_DEFINITION () renverra toujours une définition en utilisant l'ancien nom.)

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

Il semble qu'après avoir exécuté cela, le problème de changement de nom disparaisse, et donc ViewAddSchemaBinding n'a pas besoin d'être modifié ....

2
David Roodman