我有一個函數可以分割一個字符串(爲了清晰起見在末尾粘貼)。 此功能在單獨使用時按預期工作。 例子:包含在「WHERE ... IN」子句中的udf中的奇怪錯誤
SELECT * FROM TableA WHERE TableA.id IN
(
SELECT value
FROM dbo.mg_fn_Split('2#1','#')
)
我得到:
SELECT value
FROM dbo.mg_fn_Split('2#1','#')
返回
-- value --
-- 2 --
-- 1 --
-----------
但在 「其中」 的條款在本例中(更TableA上以後)使用時,如錯誤:「傳遞給LEFT或SUBSTRING函數的長度參數無效。」
表A在此用作示例。使用不同的表(假設他們有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
內聯UDF被擴展到查詢中,因此可能會有一些連接操作或過濾器以不符合預期的順序進行評估。 –
不使用連接的原因是什麼?恕我直言,如果可能的話,最好將字符串解析出來。 –
我同意Martin的評論,我相信你的函數的WHERE子句被推到你從TableA中選擇*。如果你在你的函數中註釋掉下面的和子字符串(CL.List,N.Value,CL.DelimiterLen)= @Delimiter,你會得到同樣的問題,因爲你的一個子字符串值爲-1。 –