文字列を分割する関数があります(わかりやすくするために最後に貼り付けました)。この機能は、単独で使用すると期待どおりに機能します。例:
SELECT value
FROM dbo.mg_fn_Split('2#1','#')
戻り値
-- value --
-- 2 --
-- 1 --
-----------
ただし、この例のように「WHERE IN」句で使用すると、次のようになります (tableA については後で詳しく説明します)。
SELECT * FROM TableA WHERE TableA.id IN
(
SELECT value
FROM dbo.mg_fn_Split('2#1','#')
)
「無効な長さパラメーターが LEFT または SUBSTRING 関数に渡されました」というエラーが表示されます。
ここでは例として TableA を使用します。別のテーブルを使用すると (id 列があると仮定して)、正しい結果が返されることがありますが、他のテーブルではエラーが発生します。
実行順序と関係があると思いますが、何が関数を「破損」させる可能性があるのか まだわかりません。
「代わりにこれを使用する」ではなく、「何が起こっているのか」の説明を探しています。たとえば、結合を使用して結果を取得できることを知っています。
関数定義:
-- Description: Returns a table containing the results of a string-split operation.
-- Params:
-- DelimitedList: The string to split
-- Delimiter: The delimiter char, defaults to ','
-- Columns:
-- Position - The char index of the item
-- Value - The actual item
-- =============================================
CREATE Function [dbo].[mg_fn_Split]
(
@DelimitedList nvarchar(max)
, @Delimiter nvarchar(2) = ','
)
RETURNS TABLE
AS
RETURN
(
With CorrectedList As
(
Select Case When Left(@DelimitedList, Len(@Delimiter)) <> @Delimiter Then @Delimiter Else '' End
+ @DelimitedList
+ Case When Right(@DelimitedList, Len(@Delimiter)) <> @Delimiter Then @Delimiter Else '' End
As List
, Len(@Delimiter) As DelimiterLen
)
, Numbers As
(
Select TOP( Coalesce(DataLength(@DelimitedList)/2,0) ) Row_Number() Over ( Order By c1.object_id ) As Value
From sys.columns As c1
Cross Join sys.columns As c2
)
Select CharIndex(@Delimiter, CL.list, N.Value) + CL.DelimiterLen As Position
, Substring (
CL.List
, CharIndex(@Delimiter, CL.list, N.Value) + CL.DelimiterLen
, CharIndex(@Delimiter, CL.list, N.Value + 1)
- ( CharIndex(@Delimiter, CL.list, N.Value) + CL.DelimiterLen )
) As Value
From CorrectedList As CL
Cross Join Numbers As N
Where N.Value <= DataLength(CL.List) / 2
And Substring(CL.List, N.Value, CL.DelimiterLen) = @Delimiter
)
編集:これを示すためにフィドルを設定しました: http://sqlfiddle.com/#!3/9f9ff/3