2016-08-05 15 views
1

私は現在、CSV文字列値('1;2;3')として列にIDのリストを格納しています。varbinary(max)をintのリストに分割する方法は? (他の方法で)

私はvarbinary(max)を使用するより良いアプローチ(私は信じて)で最適化したいと思います。

私はtsql関数を探しています
1。これは、整数行のセットをvarbinary(最大)
2に並列にマージします。それがint行

感謝任意のヒントのセットにvarbinary型のフィールドを分割するだろう、おかげ

+1

より良い方法は、データを正規化することです。同じ「タイプ」の情報である3つのデータ項目がある場合、それらは同じ列に属しますが、それらは*別々の行に属します。 –

+2

いいえ、それは良くないでしょう。それでも、同じ列に複数の値を保持しています。これらの値を各行に1つずつ保持する別のテーブルを作成することをお勧めします。詳細については、[データベース列に区切られたリストを格納するのは本当に悪いですか?](http://stackoverflow.com/questions/3653462/is-storing-a-delimited-list-in-a-database-columnあなたがこの質問に対する答えが**である理由の多くを見ることができます**絶対にはい!** –

+0

これは「ベストプラクティス」についての質問ではありません。私はあらかじめ計算されたコストの高い操作の結果としてこれらの値を保存しています。 – uzul

答えて

0

ソリューションは非常に疑問です。私はまた、データを正規化することをお勧めします。

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値から第九番号を抽出します。あなたはまだVARBINARYとしてデータを保存したい場合は
しかし、ここでのソリューションです。

各行に100万レコードと100万個のデータセットを持つデータセットに対してこの機能を実行しないでください。

+0

私はそれを理解するために時間をかけました:)私が本当に探しているのは、intを4バイトのメモリスロットとして並べて格納する方法です、そして文字列を使わずに。 tsqlがそれを処理できるかどうか疑問に思う – uzul

+0

いくつの値を保存したいですか?理論的には、最大30K INTカラムを持つことができます。しかし、これらの値を別のテーブルに保存することをお勧めします。抽出するのがずっと簡単です。 –

関連する問題