我正在将存储过程从MySql转换为SQL Server。该过程有一个输入参数nvarchar
/ varchar
,这是一个以逗号分隔的字符串,例如
'1,2,5,456,454,343,3464'
我需要编写一个将检索相关行的查询,在我正在使用FIND_IN_SET
的MySql中,我想知道SQL Server中的等价物是什么。
我还需要在字符串中订购ID。
原始查询是:
SELECT *
FROM table_name t
WHERE FIND_IN_SET(id,p_ids)
ORDER BY FIND_IN_SET(id,p_ids);
答案 0 :(得分:2)
like
的等效值为where
,charindex()
的等效值为order by
:
select *
from table_name t
where ','+p_ids+',' like '%,'+cast(id as varchar(255))+',%'
order by charindex(',' + cast(id as varchar(255)) + ',', ',' + p_ids + ',');
嗯,你可以使用charindex()
,但like
可以在大多数数据库中使用。
请注意,我已在字符串的开头和结尾添加了分隔符,因此464不会意外地匹配3464。
答案 1 :(得分:1)
您需要编写FIND_IN_SET函数,因为它不存在。我能想到的将分隔字符串转换为可连接对象的closet机制是创建table-valued function并在标准语句中使用结果。它需要类似于:
DECLARE @MyParam NVARCHAR(3000)
SET @MyParam='1,2,5,456,454,343,3464'
SELECT
*
FROM
MyTable
WHERE
MyTableID IN (SELECT ID FROM dbo.MySplitDelimitedString(@MyParam,','))
您需要创建一个MySplitDelimitedString
类型table-valued function来分割字符串并返回TABLE (ID INT)
个对象。
答案 2 :(得分:0)
基于集合的解决方案,它将id分成int并与基表连接,后者将利用基表id上的索引。我假设id是一个int,否则只需删除强制转换。
declare @ids nvarchar(100) = N'1,2,5,456,454,343,3464';
with nums as ( -- Generate numbers
select top (len(@ids)) row_number() over (order by (select 0)) n
from sys.messages
)
, pos1 as ( -- Get comma positions
select c.ci
from nums n
cross apply (select charindex(',', @ids, n.n) as ci) c
group by c.ci
)
, pos2 as ( -- Distinct posistions plus start and end
select ci
from pos1
union select 0
union select len(@ids) + 1
)
, pos3 as ( -- add row number for join
select ci, row_number() over (order by ci) as r
from pos2
)
, ids as ( -- id's and row id for ordering
select cast(substring(@ids, p1.ci + 1, p2.ci - p1.ci - 1) as int) id, row_number() over (order by p1.ci) r
from pos3 p1
inner join pos3 p2 on p2.r = p1.r + 1
)
select *
from ids i
inner join table_name t on t.id = i.id
order by i.r;