2016-12-13 7 views
2

Общая задачаSQL CLR скалярной функция кэшированных результаты

После перехода на SQL Server 2014, выполнение скалярной функции CLR ранее полученной различные результаты для каждого исполнения в SQL Server 2008 R2, в настоящее время производит одинаковые результаты для каждого последующий вызов.

Тест/Иллюстрация

DECLARE @i int = 0; 
WHILE @i < 10 
BEGIN 
    print dbo.getEligLoadTXID(); 
    --> Simulate delay as this code never gets called more than once every few seconds in our environment 
    WAITFOR DELAY '00:00:00.1'; 
    SET @i += 1; 
END; 

Мы в настоящее время в процессе модернизации нашей окружающей среды от SQL Server 2008 R2 для SQL Server 2014. Одна из проблем, которые мы уже запустили в специфична для исполнения скалярная функция CLR. Функция относительно проста; он генерирует внутренний идентификатор, основанный на количестве тиков (не будем спорить о необходимости/цели для этой функции).

В среде SQL Server 2008 R2 выполнение функции в цикле возвращает ожидаемые результаты (каждое исполнение приводит к новому значению). Однако при тестировании в нашей новой среде SQL Server 2014 один и тот же код возвращает ТОЛЬКО значение для каждого выполнения в цикле.

Результаты в SQL Server 2008 R2:

20161213502167209995 
20161213502168210095 
20161213502169210195 
20161213502170210295 
20161213502171210395 
20161213502172210495 
595 
20161213502174210695 
20161213502175210795 
20161213502176210895 

Результаты в SQL Server 2014:

20161213502199924787 
20161213502199924787 
20161213502199924787 
20161213502199924787 
20161213502199924787 
20161213502199924787 
20161213502199924787 
20161213502199924787 
20161213502199924787 
20161213502199924787 

Мы используем этот код, чтобы создать определенный идентификатор для каждого файла, который мы получаем от конкретного тип. Новое значение генерируется для каждого файла, но процесс SSIS, который обрабатывает его, обычно обрабатывает файл в течение 4-5 секунд. Таким образом, эта функция вызывается один раз в несколько секунд, из совершенно разных соединений, но мы все равно возвращаем повторяющиеся результаты.

Возвращаемое значение меняется периодически, поэтому его не так, как будто мы получаем только одно значение в течение всего дня, но в течение периодов времени, будь то 3 секунды или 30 секунд, функция вернет тот же результат.

Что нам не хватает?

CLR Функция Def

[SqlFunction(IsDeterministic = true, IsPrecise = true)] 
public static String getTransactionID() 
{ 
    DateTime NOW = DateTime.Now; 

    long ticks = NOW.Ticks - new DateTime(NOW.Year, NOW.Month, NOW.Day, 0, 0, 0, 0).Ticks; 

    return String.Format("{0:0000}{1:00}{2:00}{3}", NOW.Year, NOW.Month, NOW.Day, ticks.ToString()); 
} 

ответ

5

Это ожидаемое поведение, начиная с SQL Server 2012.

Вопрос заключается в том, что вы указали, с помощью атрибута SqlFunction, что эта функция должна рассматриваться как «Детерминированный»:

IsDeterministic = true 

Детерминированная функция возвращает то же значение для тех же входных значений. И учитывая, что у вашей функции нет каких-либо входных параметров, все ее исполнения по существу одинаковы.

Такое поведение является огромным усилением производительности для функций, которые действительно детерминированы. Однако, поскольку ваша функция должна возвращать другое значение за каждое исполнение, оно фактически не детерминировано.

Чтобы исправить это, вы должны быть в состоянии установить IsDeterministic = false, или просто удалить IsDeterministic = true,, так как значение по умолчанию для IsDeterministic является false.

P.S. Я знаю, что вы сказали, не спорить о том, почему у вас есть эта определенная функция, но это лишь в случае, если вы (или другие) не знали об этом, то текущем значение клеща должно быть выставлено в DMV:

SELECT [cpu_ticks] FROM sys.dm_os_sys_info; 

PPS Также лучше использовать типы Sql* для входных параметров и возвращаемых значений. Значение, используйте SqlString вместо String для типа возврата. Для этого может потребоваться добавление using System.Data.SqlTypes;.

+1

Благодарим за отзыв! Вы не только ответили на мой вопрос, но и дали много подробностей. –