Bagaimana cara mematikan SCHEMABINDING untuk tampilan tanpa membuatnya kembali?


Jawaban:


11

Iya nih. Ada baiknya Anda menggunakan SCHEMABINDING (kami selalu melakukannya) dan kadang-kadang Anda harus menghapusnya untuk mengubah objek dependen. ALTER saja tampilan

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

saya juga, tapi terkadang objek lain (fungsi, tampilan) bergantung pada yang ini. Jadi akan baik untuk menandai / menghapus tanda bendera ini untuk sementara waktu :). Jadi tidak mungkin dalam versi db saat ini, ya?
garik

@ garik: benar, saya punya masalah yang sama. Jalankan ALTER pada setiap objek dependen ... Kapan saja SQL Server akan menegakkan aturan: Anda tidak dapat "mematikan" karena ini akan menyebabkan inkonsistensi
gbn

8

Tidak akan mengubah tampilan memungkinkan Anda untuk melakukan ini? Ketika Anda membuat tampilan yang akan Anda lakukan:

CREATE VIEW
WITH SCHEMABINDING
AS
SELECT stmt
GO

jadi, kehilangan klausa DENGAN:

ALTER VIEW viewname
AS
SELECT stmt
GO

Lihat ALTER VIEW di MSDN


5

Setelah mencari-cari selama berjam-jam, saya membuat 2 proc yang disimpan untuk ini. Semoga ini bisa membantu seseorang

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

Dan untuk menempatkan 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

Ini disediakan "sebagaimana adanya" ...


2

Versi ViewRemoveSchemaBinding ini berfungsi bahkan jika tampilan telah diubah namanya sejak dibuat. (Masalahnya adalah jika tampilan telah diubah namanya, OBJECT_DEFINITION () masih akan mengembalikan definisi menggunakan nama lama.)

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

Tampaknya setelah menjalankan ini masalah penggantian nama hilang, dan begitu ViewAddSchemaBinding tidak perlu diubah ....


1
Ini tidak berhasil, karena perintahnya masih mengandung 'WITH SCHEMABINDING' - untuk memperbaikinya, ubah penggunaan RIGHTmenjadi:RIGHT(@Command, LEN(@Command) - (@PositionShemaBinding + LEN('WITH SCHEMABINDING')))
Cocowalla
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.