ฉันจะปิดการวางแผนสำหรับมุมมองโดยไม่สร้างใหม่ได้อย่างไร


คำตอบ:


11

ใช่. เป็นเรื่องดีที่คุณใช้ SCHEMABINDING (เราดำเนินการเสมอ) และบางครั้งคุณต้องลบมันออกเพื่อเปลี่ยนวัตถุที่ต้องพึ่งพา เพียงแค่เปลี่ยนมุมมอง

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

ฉันทำเช่นนั้น แต่บางครั้งวัตถุอื่น ๆ (ฟังก์ชั่นมุมมอง) ขึ้นอยู่กับวัตถุนี้ ดังนั้นจึงเป็นการดีที่จะทำเครื่องหมาย / ไม่เลือกธงนี้เป็นเวลา :) ดังนั้นจึงเป็นไปไม่ได้ในเวอร์ชันปัจจุบันของ db ใช่
garik

@garik: ถูกต้องฉันมีปัญหาเดียวกัน เรียกใช้การเปลี่ยนแปลงบนแต่ละวัตถุที่อ้างถึง ... ณ เวลาใดก็ตาม SQL Server จะบังคับใช้กฎ: คุณไม่สามารถ "ปิด" เพราะจะทำให้เกิดความไม่สอดคล้องกัน
gbn

8

ALTER VIEW จะไม่อนุญาตให้คุณทำสิ่งนี้หรือไม่ เมื่อคุณสร้างมุมมองคุณจะทำ:

CREATE VIEW
WITH SCHEMABINDING
AS
SELECT stmt
GO

ดังนั้นแพ้ด้วยคำสั่ง:

ALTER VIEW viewname
AS
SELECT stmt
GO

ดูALTER VIEW บน MSDN


5

หลังจากดูไปหลายชั่วโมงฉันได้สร้าง proc ที่เก็บไว้ 2 อันสำหรับสิ่งนี้ หวังว่านี่จะช่วยใครซักคน

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

และเพื่อวางแผนงาน:

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

มันมีให้ "ตามที่เป็น" ...


2

ViewRemoveSchemaBinding รุ่นนี้ใช้งานได้แม้ว่ามุมมองนั้นจะถูกเปลี่ยนชื่อตั้งแต่ถูกสร้างขึ้น (ปัญหาคือถ้าเปลี่ยนมุมมองแล้ว OBJECT_DEFINITION () จะยังคงส่งคืนคำจำกัดความโดยใช้ชื่อเดิม)

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

ดูเหมือนว่าหลังจากใช้งานปัญหาการเปลี่ยนชื่อจะหายไปและดังนั้น ViewAddSchemaBinding จึงไม่จำเป็นต้องเปลี่ยนแปลง ....


1
สิ่งนี้ไม่ทำงานเนื่องจากคำสั่งยังคงมี 'With SCHEMABINDING' - เพื่อแก้ไขให้เปลี่ยนการใช้RIGHTเป็น:RIGHT(@Command, LEN(@Command) - (@PositionShemaBinding + LEN('WITH SCHEMABINDING')))
Cocowalla
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.