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

Réponses:

11

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

ALTER VIEW myView
--Remove this WITH SCHEMABINDING
AS
SELECT ...
GO
gbn
la source
moi aussi, mais parfois d'autres objets (fonctions, vues) dépendent de celui-ci. Il sera donc bon de marquer / décocher ce drapeau pendant un certain temps :). C'est donc impossible dans la version actuelle de db, oui?
garik
@garik: correct, j'ai le même problème. Exécutez ALTER sur chaque objet dépendant ... À tout moment, SQL Server appliquera les règles: vous ne pouvez pas "désactiver" car cela conduirait à une incohérence
gbn
8

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

SQLRockstar
la source
5

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" ...

boblemar
la source
2

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 () renvoie 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é ....

David Roodman
la source
1
Cela ne fonctionne pas, car la commande contient toujours 'WITH SCHEMABINDING' - pour le corriger, changez l'utilisation de RIGHT:RIGHT(@Command, LEN(@Command) - (@PositionShemaBinding + LEN('WITH SCHEMABINDING')))
Cocowalla