SQL Server 2008 - sp_refreshview взламывает некоторые виды

Я унаследовал довольно значительный проект, который широко использует представления SQL Server (2005 и 2008).

Одним из шагов процесса сборки является вызов хранимой процедуры sp_refreshviews, чтобы убедиться, что никакие изменения в таблицах не нарушили наши представления. Это прекрасно работает... за исключением трех или четырех (из 200 +) просмотров....

С ними он просто взрывается - дает нечетные сообщения об ошибках, например

Msg 15165, уровень 16, состояние 1, Процедура sp_refreshsqlmodule_internal, строка 55
Не удалось найти объект 'vYourViewNameHere', или вы не имеют разрешение.

который мертв неправильно - этот вид существует, и я определенно может выбрать из него.

Я не могу найти какую-либо хорошую краткую информацию о , почему это происходит, что вызывает ее... любые идеи? Могу ли я что-нибудь сделать, чтобы обнаружить такие проблематичные взгляды? Могу ли я изменить их definitino, чтобы они снова обновлялись?

Обновление: Я зарегистрировал отчет об ошибке в Microsoft Connect для этого - если вы согласитесь, это кажется странным и нуждается в исправлении, проголосуйте за него!

https://connect.microsoft.com/SQLServer/feedback/details/676728/sp-refreshview-crashes-with-misleading-error-on-views-with-schemabinding

Ответ 1

Я заметил в комментариях, что вы упоминаете, что имеет SCHEMABINDING. Я могу почти гарантировать, что это проблема. Книги в Интернете специально говорит, что это используется для не связанных с схемой представлений.

Представленный с помощью схемы вид не может допускать взлома, так что обновление метаданных не требуется. Вы можете спокойно пропустить его.

Вы можете идентифицировать все виды schemabound следующим образом:

SELECT * FROM sys.views WHERE OBJECTPROPERTY(object_id, 'IsSchemaBound')=1

Ответ 2

Я столкнулся с той же ошибкой при использовании sp_helptext. В моем случае причиной было использование sp_rename для переименования представления. Следующий код воспроизводит эту ошибку.

create view demo as select dummy = 1
go

exec sp_rename 'demo', 'new_demo'
go

exec sp_refreshview 'new_demo'
go

Единственное решение - это вручную изменить представление. Примените это исправление к вышеуказанному решению, и вы получите:

create view demo as select dummy = 1
go

exec sp_rename 'demo', 'new_demo'
go

-- This statement fixes the problem
alter view new_demo as select dummy = 1
go

exec sp_refreshview 'new_demo'
go

Ответ 3

Мое воплощение этой ошибки:

Msg 8116, уровень 16, состояние 1, процедура sp_refreshsqlmodule_internal, Строка 75 Тип данных аргумента int недопустим для аргумента 1 подстроки функция.

Это сообщение об ошибке сообщалось в разных местах в db script. Я бы сказал, что неправильно. Если я прокомментировал SQL, то эта ошибка была отправлена, такая же ошибка будет сообщаться в другом месте.

Я прокомментировал следующий вызов в моем script как обходной путь, и script завершится успешно.

-- EXECUTE sp_refreshview @viewName;

Примечание. Моя база данных не сообщила о наличии представлений schemabound при выполнении запроса, предложенного в смежном ответе RThomas fooobar.com/questions/521748/...

ОБНОВЛЕНИЕ - РЕШЕНИЕ:

После того, как наша база данных script успешно запущена с командой sp_refreshview, закомментированной (см. выше), мы сразу же запустили код обновления представления, и он тоже был успешным.

- Страница Этот ответ не имеет для меня смысла, как он смог успешно работать, однако я документирую его здесь, если он окажется полезным кому-то другому.

Ответ 4

Чтобы узнать, какое представление является вашей проблемой, добавьте печать в обычный sppRefreshViews. Здесь ничего не разрушилось, но я думал, что поделюсь.

CREATE procedure sppRefreshViews2

    as
    declare @t varchar (1024)

    declare tbl_cur cursor for
    select TABLE_NAME from INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE = 'VIEW' and table_name like 'sp%'
    OPEN tbl_cur

    FETCH NEXT from tbl_cur INTO @t
    WHILE @@FETCH_STATUS = 0
    BEGIN
    print      @t 
    exec ('sp_refreshview ''' + @t + '''')
    FETCH NEXT from tbl_cur INTO @t
    END

    CLOSE tbl_cur
    DEALLOCATE tbl_Cur