31

How do I switch off SCHEMABINDING for a view without recreating it?

Nick Chammas
  • 14,810
  • 17
  • 76
  • 124
garik
  • 6,782
  • 10
  • 44
  • 56

5 Answers5

16

Yes. It's good that you use SCHEMABINDING (we do always) and sometimes you have to remove it to change a dependent object. Just ALTER the view

ALTER VIEW myView
--Remove this WITH SCHEMABINDING
AS
SELECT ...
GO
gbn
  • 70,237
  • 8
  • 167
  • 244
15

After looking around for hours, I created 2 stored proc for this. Hope this helps someone

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

And to put the 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

It is provided "as is"...

boblemar
  • 251
  • 2
  • 3
10

Won't ALTER VIEW allow for you to get this done? When you create a view you would do:

CREATE VIEW
WITH SCHEMABINDING
AS
SELECT stmt
GO

so, lose the WITH clause:

ALTER VIEW viewname
AS
SELECT stmt
GO

See ALTER VIEW on MSDN

gbn
  • 70,237
  • 8
  • 167
  • 244
SQLRockstar
  • 6,355
  • 27
  • 48
3

This version of ViewRemoveSchemaBinding works even if the view has been renamed since it was created. (The problem is that if the view has been renamed, OBJECT_DEFINITION() will still return a definition using the old name.)

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

It seems that after running this the renaming issue goes away, and so ViewAddSchemaBinding doesn't need to be altered....

1

You might want to do something like..

@Command = REPLACE(@Command,'WITH SCHEMABINDING','-- WITH SCHEMABINDING')

This would allow you to scan the --WITH SCHEMABINDING to reinstate the schemabinding after the object was altered.

Rohit Gupta
  • 2,116
  • 8
  • 19
  • 25
Rob George
  • 19
  • 2