2016-08-05 20 views
1

我正在將CSV列表中的id列表存儲爲CSV字符串值('1;2;3')如何將varbinary(max)分割爲一個整數列表? (和另一種方式)

我想優化一個更好的方法(我相信)會使用varbinary(max)。

我在尋找tsql的功能
1。這將並排合併一組整數行到varbinary(max)
2。這將在VARBINARY場分成一組INT行

知道的任何提示,謝謝

+1

更好的方法是將數據標準化。如果你有三項數據是相同的「類型」信息,那麼是的,它們屬於同一列,但它們屬於*分開的*行。 –

+2

不會更好。它仍然會保持同一列中的多個值。你最好創建另一個表來爲每一行保存這些值。有關更多信息,請閱讀[在數據庫列中存儲分隔列表真的很糟糕嗎?](http://stackoverflow.com/questions/3653462/is-storing-a-delimited-list-in-a-database-column那麼你會看到很多原因,爲什麼這個問題的答案是**絕對是!** –

+0

這不是關於'最佳實踐'的問題。我將這些值存儲爲預先計算的代價高昂操作的結果。 – uzul

回答

0

解決方案是非常值得懷疑的。我也建議規範化數據。
但是,如果你仍然要存儲的數據作爲VARBINARY,這裏是解決方案:

CREATE FUNCTION dbo.fn_String_to_Varbinary(@Input VARCHAR(MAX)) 
RETURNS VARBINARY(MAX) AS 
BEGIN 
DECLARE @VB VARBINARY(MAX); 
WITH CTE as (
    SELECT CAST(CAST(LEFT(IT,CHARINDEX(';',IT)-1) AS INT) as VARBINARY(MAX)) as VB, RIGHT(IT,LEN(IT) - CHARINDEX(';',IT)) AS IT 
    FROM (VALUES (@Input)) as X(IT) union all 
    SELECT VB + CAST(CAST(LEFT(IT,CHARINDEX(';',IT)-1) AS INT) as VARBINARY(MAX)) as VB, RIGHT(IT,LEN(IT) - CHARINDEX(';',IT)) AS IT FROM CTE WHERE LEN(IT) > 1 
) 
SELECT TOP 1 @VB = VB FROM CTE 
ORDER BY LEN(VB) DESC 
RETURN @VB 
END 
GO 
DECLARE @Input VARCHAR(MAX) = '421;1;2;3;5000;576;842;375;34654322;18;67;000001;1232142334;' 
DECLARE @Position INT = 9 
DECLARE @VB VARBINARY(MAX) 
SELECT @VB = dbo.fn_String_to_Varbinary(@Input) 
SELECT @VB, CAST(SUBSTRING(@VB,4*(@Position-1)+1,4) AS INT) 
GO 

功能轉換成字符串VARBINARY然後腳本提取從VARBINARY值9日數字。

不要針對每行有百萬條記錄和百萬個數字的數據集運行此功能。

+0

花了我一些時間來理解它:)我真正想要的是一種將ints作爲4字節內存插槽並排存儲的方式,並且不再使用字符串。想知道tsql是否可以處理這個問題 – uzul

+0

你想存儲多少個值?理論上,你可以有高達30K的INT列。不過,我最好建議將這些值存儲在單獨的表格中。提取起來會更容易/更快速。 –

相關問題