2016-12-13 51 views
2

通用問題SQL CLR標量函數緩存結果

移動到SQL Server 2014之後,這在以前產生在SQL Server 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; 

目前我們正處在從SQL Server 2008升級我們的環境R2到SQL Server的過程2014年的一個我們已經遇到的問題是具體到執行一個CLR標量函數。功能相對簡單;它會根據滴答的數量生成一個內部ID(我們不要爭論這個函數的需要/目的)。

在SQL Server 2008 R2環境中,在循環中執行函數會返回預期結果(每次執行都會產生一個新值)。但是,在我們新的SQL Server 2014環境中進行測試時,相同的代碼將爲循環中的每個執行返回SAME值。

結果在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 

我們正在使用此代碼生成每個文件中的特定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 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

謝謝你的迴應!你不僅回答了我的問題,而且還提供了大量的後續細節。 –