2012-03-01 3 views
3

У меня есть эта функция с именем fn_blah, которая находится в базе данных Master SQL Server 2000. Эта же функция находится в базе данных master SQL Server 2008. На поле SQL Server 2000, функция работает нормально при другом контексте базы данных без указания владельца (например, ПСЭ.):Пользовательская функция в основной базе данных не будет выполнена

User OtherDB1; 
EXEC fn_blah; 

Но на поле SQL Server 2008, приведенный выше запрос не будет работать. Будет работать, если вы измените контекст базы данных на master, а затем запустите его, как указано выше. Или вы запускаете следующее:

EXEC master.dbo.fn_blah 

Кто-нибудь видел такое поведение раньше? Любая помощь приветствуется. Благодаря!

+3

** Не ставьте объекты пользователя в мастер. ** Проблема решена! – JNK

+0

Были изменения в том, как обрабатываются схема и владелец с SQL Server 2000 до SQL Server 2005. Я не помню их всех, но если вы посмотрите на изменения между ними (должна быть документация на веб-сайте Microsoft сайты где-то), вы должны уметь понять, почему это изменилось, но так как вы знаете, как заставить его работать в обоих, действительно ли это стоит усилий? – David

+0

Ваш контекст немного запутанный. Вы говорите, что вы вызываете * функцию *, используя * EXEC *? –

ответ

5

База данных master - это системная база данных, в которой хранится вся информация обо всем остальном на вашем сервере.

Когда вы помещаете объекты пользователя в master, вы можете получить к ним доступ без контекста базы данных.

Это по существу непреднамеренное поведение - двигатель проверяет наличие некоторых объектов (в зависимости от имени объекта и версии SQL Server) перед проверкой текущего контекста БД.

Это действительно плохая идея, а не что-то для разработки ваших процессов. Могут возникнуть всевозможные проблемы, не в последнюю очередь из которых те объекты в master, которые будут перезаписаны при обновлении или перезагрузке вашего сервера, поскольку мастер не предназначен для хранения пользовательских объектов!

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

+3

Или используйте собственную служебную базу данных вместо мастера. Если вы не хотите применять имена трех частей, вы можете создать синоним, а затем ссылаться на имена из двух частей. Вы никогда не должны * хотеть * писать одночастные имена для ЛЮБОГО типа объекта, ИМХО. –

+0

Так есть ли разрешение на уровне области видимости, которое может быть предоставлено на функции, которая может заставить ее увидеть или вызвать из любого контекста базы данных без использования имен частей вообще? – Chinesinho

+0

@Chinesinho Я не уверен, но я говорю вам, что это ужасная идея. Это может привести к разным вопросам. Предположим, что у вас есть 'master.dbo.fn_stuff' и' somedatabase.dbo.fn_stuff'. Если вы выполняете 'fn_stuff' с' somedatabase' в качестве текущего контекста (но без указания его), вы запустите то, что вы не ожидали запускать. Проектирование процессов вокруг этого поведения является антипаттерном и его следует избегать. – JNK

Смежные вопросы