Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/27.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 选择使用以逗号分隔的字符串参数的行_Sql_Sql Server_Tsql - Fatal编程技术网

Sql 选择使用以逗号分隔的字符串参数的行

Sql 选择使用以逗号分隔的字符串参数的行,sql,sql-server,tsql,Sql,Sql Server,Tsql,我正在将一个存储过程从MySql转换为SQL Server。该过程有一个输入参数nvarchar/varchar,它是一个逗号分隔的字符串,例如 '1,2,5,456,454,343,3464' 我需要编写一个查询来检索相关的行,在MySql中我正在使用FIND_in_SET,我想知道SQL Server中的等价物是什么 我还需要按照字符串中的顺序排列ID 原始查询是: SELECT * FROM table_name t WHERE FIND_IN_SET(id,p_ids) OR

我正在将一个存储过程从MySql转换为SQL Server。该过程有一个输入参数nvarchar/varchar,它是一个逗号分隔的字符串,例如

'1,2,5,456,454,343,3464'
我需要编写一个查询来检索相关的行,在MySql中我正在使用FIND_in_SET,我想知道SQL Server中的等价物是什么

我还需要按照字符串中的顺序排列ID

原始查询是:

 SELECT * 
 FROM table_name t
 WHERE FIND_IN_SET(id,p_ids)
 ORDER BY FIND_IN_SET(id,p_ids);
等价物类似于where,然后是订单的charindex:

当然,您可以同时使用charindex,但在大多数数据库中都可以使用类似的方法

请注意,我已经在字符串的开头和结尾添加了分隔符,因此464不会意外地与3464匹配。

等价物类似于where和then charindex,用于order by:

当然,您可以同时使用charindex,但在大多数数据库中都可以使用类似的方法


请注意,我在字符串的开头和结尾添加了分隔符,因此464不会意外地与3464匹配。

您需要编写FIND\u IN\u SET函数,因为它不存在。我能想到的将分隔字符串转换为可连接对象的密室机制是创建并在标准in语句中使用结果。它需要类似于:

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 ID INT对象

您需要编写FIND_IN_SET函数,因为它不存在。我能想到的将分隔字符串转换为可连接对象的密室机制是创建并在标准in语句中使用结果。它需要类似于:

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 ID INT对象

一种基于集合的解决方案,它将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;

一种基于集合的解决方案,它将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;

您还可以尝试使用正则表达式从逗号分隔的字符串中获取输入值:

从id所在的表名称中选择* 从dual中选择regexp_substrp_ids,[^,]+',1,level
通过regexp_substrp_id,[^,]+',1连接,级别不为空

您也可以尝试使用正则表达式从逗号分隔的字符串中获取输入值:

从id所在的表名称中选择* 从dual中选择regexp_substrp_ids,[^,]+',1,level
通过regexp_substrp_id,[^,]+',1连接,级别不为空

您需要将字符串解析为值、使用动态sql或将列表更改为表参数。为此,我将避免使用动态sql,除非您绝对必须这样做,否则从性能角度来看,表参数可能是最好的选择。Tx,我将阅读有关表参数的内容。您需要将字符串解析为值,使用动态sql,或将列表更改为表参数。为此,我将避免使用动态sql,除非您绝对必须这样做,否则表参数可能是性能方面的最佳选择,其次是拆分字符串。Tx,我将阅读有关表参数的内容