Odpowiedzi:
Tak. Dobrze, że używasz SCHEMABINDINGU (zawsze tak robimy), a czasem musisz go usunąć, aby zmienić zależny obiekt. Wystarczy zmienić widok
ALTER VIEW myView
--Remove this WITH SCHEMABINDING
AS
SELECT ...
GO
Czy ALTER VIEW nie pozwoli ci tego zrobić? Kiedy tworzysz widok, robisz:
CREATE VIEW
WITH SCHEMABINDING
AS
SELECT stmt
GO
więc zgub klauzulę WITH:
ALTER VIEW viewname
AS
SELECT stmt
GO
Zobacz ALTER VIEW na MSDN
Po rozglądaniu się godzinami, stworzyłem do tego 2 przechowywane procy. Mam nadzieję, że to komuś pomoże
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
I umieścić 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
Jest dostarczany „tak jak jest” ...
Ta wersja ViewRemoveSchemaBinding działa, nawet jeśli nazwa widoku została zmieniona od czasu jego utworzenia. (Problem polega na tym, że jeśli zmieniono nazwę widoku, OBJECT_DEFINITION () nadal zwróci definicję przy użyciu starej nazwy).
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
Wygląda na to, że po uruchomieniu tego problemu zmiana nazwy znika, więc ViewAddSchemaBinding nie musi być zmieniany ...
RIGHT
na:RIGHT(@Command, LEN(@Command) - (@PositionShemaBinding + LEN('WITH SCHEMABINDING')))