Есть ли способ сделать этот UDF детерминированным?

Я предполагаю, что это не детерминировано просто потому, что DB_NAME() не является детерминированным? Если DB_NAME() не является детерминированным, почему он не детерминирован?

 ALTER FUNCTION [TheSchema].[udf_IS_PRODUCTION] () RETURNS bit WITH SCHEMABINDING AS BEGIN RETURN CASE WHEN DB_NAME() = 'PRODUCTION' THEN CONVERT(bit, 1) ELSE CONVERT(bit, 0) END END 

Обновление: эта версия работает, является детерминированной, позволяет использовать один и тот же код в любой базе данных и удаляет жесткое кодирование имени базы данных (что также позволяет мне удалить другое исключение системы безопасности системы из-за кодирования имени базы данных)

 ALTER FUNCTION [TheSchema].[udf_IS_PRODUCTION] () RETURNS bit WITH SCHEMABINDING AS BEGIN RETURN (SELECT IS_PRODUCTION FROM TheSchema.IS_PRODUCTION) END 

FYI Это фрагмент кода в системе самообслуживания системы, который я использую для мониторинга потенциальных проблем.

  SELECT 'Non-deterministic Scalar UDF' AS Problem ,QUOTENAME(ROUTINE_SCHEMA) + '.' + QUOTENAME(ROUTINE_NAME) AS ROUTINE_NAME FROM INFORMATION_SCHEMA.ROUTINES WITH (NOLOCK) WHERE IS_DETERMINISTIC = 'NO' AND ROUTINE_TYPE = 'FUNCTION' AND DATA_TYPE <> 'TABLE' ORDER BY ROUTINE_SCHEMA ,ROUTINE_NAME 

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

 ALTER FUNCTION [TheSchema].[udf_IS_PRODUCTION] () RETURNS bit WITH SCHEMABINDING AS BEGIN RETURN CONVERT(bit, 1) END 

И разверните его в тестовой базе данных:

 ALTER FUNCTION [TheSchema].[udf_IS_PRODUCTION] () RETURNS bit WITH SCHEMABINDING AS BEGIN RETURN CONVERT(bit, 0) END 

Это может показаться глупым, но IMO имя базы данных не должно быть «жестко закодировано», а не возвращаемое значение некоторого UDF.

Еще лучше, просто поместите эту информацию в таблицу конфигурации где-нибудь.

Не могли бы вы, возможно, переписать свою функцию, чтобы не определять DB_NAME () внутренне, но получить ее в качестве параметра?

 ALTER FUNCTION [TheSchema].[udf_IS_PRODUCTION] (DatabaseName VARCHAR(255)) RETURNS bit WITH SCHEMABINDING AS BEGIN RETURN CASE WHEN DatabaseName = 'PRODUCTION' THEN CONVERT(bit, 1) ELSE CONVERT(bit, 0) END END 

Не должно быть детерминированным, не так ли?

Когда вы вызываете его, вы можете использовать DB_NAME() в качестве функции для определения имени базы данных

Детерминированная функция, по определению, является функцией, возвращаемое значение которой однозначно идентифицируется значениями ее аграментов.

Теперь, учитывая аргументы DB_NAME() (которых нет), можете ли вы сказать, что он вернет?

В строгом смысле детерминизма результат не основан на входных параметрах, а на состоянии внешнего объекта, который не находится под вашим контролем.

Имя может быть изменено и т. Д.

 Alter Database Modify Name = new_name 

В 2005 году SQL не предотвращает создание функции, но когда я попробовал ее по схеме по умолчанию. Если вы столкнетесь с ситуацией, когда она отказывается принять функцию, основанную на недетерминизме, и вам нужно ее обойти (с рисками и т. Д.), Маршрут вокруг нее состоит в создании представления, которое использует эту функцию, а затем выберите из вид внутри функции.

Interesting Posts

Каков наилучший способ хранения даты без года в базе данных SQL?

Выбор подмножества строк, превышающих процент от общих значений

Проблемы в LINQ to SQL со строкой содержат Escape seqence Backspace – C #

Сравните дату и месяц в sql-сервере для системы оповещения

Почему SELECT FROM sys.dm_db_index_usage_stats возвращает две строки / таблицу?

Ошибка .NET Framework возникла во время выполнения пользовательской подпрограммы или агрегата – SSIS 2017

Как я могу применять правила уникальности, которые включают более одной таблицы?

Отображение символов / поиск и замена символа по символу в SQL Server 2008 R2

SELECT @@ ROWCOUNT в SSMS (2014,2016)

Перекрестная привязка функции с табличной оценкой

Возвращаемое значение из функции в SQL Server

Добавьте клиентов с тем же именем и добавьте их в другую таблицу

Использовать SSIS для миграции и нормализации базы данных

Как правильно сопоставить таблицы SQL Server с DataTables?

Извлечение данных из двух разных таблиц и вывод в значение столбца

Давайте будем гением компьютера.