2016-12-13 1 views
2

일반 문제SQL CLR 스칼라 함수 캐시 결과

SQL 서버 2014로 이동 한 후, 이전에 SQL 서버 2008 R2의 각 실행에 대한 다른 결과를 생성 된 CLR 스칼라 함수의 실행은 이제 각각에 대해 동일한 결과를 얻을 후속 통화.

테스트/그림

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; 

우리는 R2 SQL 서버에 SQL 서버 2008에서 우리의 환경을 업그레이드하는 과정에서 현재 우리가로 실행 한 문제의 2014 년 하나의 실행에 따라 다릅니다 CLR 스칼라 함수. 이 기능은 비교적 간단합니다. 그것은 틱의 수를 기반으로 내부 ID를 생성합니다 (이 함수의 필요성/목적에 대해 논쟁하지 않겠습니다).

SQL Server 2008 R2 환경에서 루프에서 함수를 실행하면 예상 된 결과가 반환되고 각 실행 결과가 새로운 값으로 반환됩니다. 그러나 새로운 SQL Server 2014 환경에서 테스트 할 때 동일한 코드가 루프의 각 실행에 대해 SAME 값을 반환합니다. SQL Server 2008 R2의

결과 : SQL Server의

20161213502167209995 
20161213502168210095 
20161213502169210195 
20161213502170210295 
20161213502171210395 
20161213502172210495 
595 
20161213502174210695 
20161213502175210795 
20161213502176210895 

결과 2014 :

20161213502199924787 
20161213502199924787 
20161213502199924787 
20161213502199924787 
20161213502199924787 
20161213502199924787 
20161213502199924787 
20161213502199924787 
20161213502199924787 
20161213502199924787 

우리는 우리가 특정의 수신 각 파일에 대한 특정 ID를 생성하기 위해이 코드를 사용하는 유형. 새 값이 모든 파일에 대해 생성되지만이 작업을 처리하는 SSIS 프로세스는 일반적으로 파일 당 4 ~ 5 초가 걸립니다. 따라서이 함수는 완전히 다른 연결에서 몇 초에 한 번 호출되지만 여전히 중복 결과가 반환됩니다.

반환 값은 주기적으로 변경되므로 하루 종일 하나의 값만 반환되는 것과 달리 시간이 3 초인지 30 초인지에 관계없이 함수는 동일한 결과를 반환합니다.

무엇이 누락 되었습니까?

CLR 기능은 데프

[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 서버에서 시작, 예상되는 동작 2012

문제는이 기능을 처리해야한다고는 SqlFunction 속성을 통해, 사용자가 지정한 것입니다 "결정 론적":

IsDeterministic = true 

확정적 함수는 동일한 값을 반환합니다. 동일한 입력 값에 대해 함수에 입력 매개 변수가 없다는 것을 고려하면 모든 실행은 본질적으로 동일합니다.

이 동작은 진정으로 결정 성있는 함수의 성능을 크게 향상시킵니다. 그러나 함수는 각 실행마다 다른 값을 반환하기 때문에 실제로 결정적이지는 않습니다.

이 문제를 해결하려면, 당신은 IsDeterministic = false을 설정하거나 IsDeterministicfalse 인의 기본 값 이후 IsDeterministic = true,를 제거 할 수 있어야한다.

P. 난 당신이 특정 기능이 이유에 대해 주장하는 것이 아니라 단지 현재의 틱 값이 DMV에 노출되어야합니다 (또는 다른 사람이) 그것을 인식되지 않은 경우에 언급하지 말라고 알고

SELECT [cpu_ticks] FROM sys.dm_os_sys_info; 

조달청 또한 입력 매개 변수 및 반환 값에 Sql* 유형을 사용하는 것이 가장 좋습니다. 반환 유형으로 String 대신 SqlString을 사용하십시오. 이 경우 using System.Data.SqlTypes;을 추가해야 할 수 있습니다.

+1

응답 해 주셔서 감사합니다. 당신은 내 질문에 대답했을뿐만 아니라 많은 후속 세부 사항을주었습니다. –