使用fn split

时间:2017-03-08 18:14:01

标签: sql tsql

正确插入,但在插入

时对id进行排序

如果我执行存储过程参数username = dynamic和id = 19,1,10 然后当我查看收藏夹表格时,我看到:

enter image description here

INSERT INTO Favorites(username, id) 
SELECT  @username, i.item
FROM fnSplit(@id, ',') i
INNER JOIN dbo.Link f on f.id = i.item
WHERE id IS NOT NULL

有关拆分功能的更多信息: https://msdn.microsoft.com/en-us/library/mt684588.aspx 注意:我为函数使用了不同的名称,但它是一样的

2 个答案:

答案 0 :(得分:1)

我相信您的inner join正在改变订单。由于您仅将其用于过滤,因此您可以将inner join更改为where exists。这应该保留顺序:

INSERT INTO Favorites( username, id )
SELECT  @username, i.item
FROM fnSplit(@id, ',') i
WHERE EXISTS
(
   SELECT 1
   FROM dbo.Link f
   WHERE f.id = i.item AND f.id IS NOT NULL
)

答案 1 :(得分:0)

示例

Declare @username varchar(50) = 'dynamic'
Declare @favorite varchar(50) = '19,1,10'

Insert Into Favorites (username,id) 
Select @username,f.ID
 From  [dbo].[udf-Str-Parse](@favorite,',') i
 Join  dbo.Link f on f.id = i.RetSeq
 Where f.ID is not null
 Order By RetSeq                  -- << Notice we added an Order By

如果它有助于可视化:

Select * From  [dbo].[udf-Str-Parse]('19,1,10',',')

<强>返回

RetSeq  RetVal
1       19
2       1
3       10

将提供序列(RetSeq)

的TVF
CREATE FUNCTION [dbo].[udf-Str-Parse] (@String varchar(max),@Delimiter varchar(10))
Returns Table 
As
Return (  
    Select RetSeq = Row_Number() over (Order By (Select null))
          ,RetVal = LTrim(RTrim(B.i.value('(./text())[1]', 'varchar(max)')))
    From  (Select x = Cast('<x>' + replace((Select replace(@String,@Delimiter,'§§Split§§') as [*] For XML Path('')),'§§Split§§','</x><x>')+'</x>' as xml).query('.')) as A 
    Cross Apply x.nodes('x') AS B(i)
);
--Thanks Shnugo for making this XML safe
--Select * from [dbo].[udf-Str-Parse]('Dog,Cat,House,Car',',')
--Select * from [dbo].[udf-Str-Parse]('John Cappelletti was here',' ')
--Select * from [dbo].[udf-Str-Parse]('this,is,<test>,for,< & >',',')
--Performance On a 5,000 random sample -8K 77.8ms, -1M 79ms (+1.16), -- 91.66ms (+13.8)