[英]Comma Delimited SQL string Need to separated
I have this string that i am getting from .net application A,B,C,D,E,F, 我有这个字符串,我从.net应用程序A,B,C,D,E,F,
I wanted to write a sql select statement like 我想编写一个像sql select语句一样的
set @string = 'A,B,C,D,E,F'
select * from tbl_test
where tbl_test.code in (@string)
This wont work in t-SQL because it is using the @string
as one string it is not separating the values. 这在t-SQL中不起作用,因为它使用
@string
作为一个字符串,而不是将值分开。 Is there any ways i can do this? 有什么方法可以做到这一点吗?
3 options 3个选项
Very frequently asked question! 很常见的问题! What you want is a table-valued function.
你想要的是一个表值函数。
But don't reinvent the wheel by writing your own, I found dozens just by Googling sql split
. 但是不要通过编写自己来重新发明轮子,我通过Googling
sql split
找到了几十个。 Here's one from Microsoft: 这是来自微软的一个:
http://code.msdn.microsoft.com/SQLExamples/Wiki/View.aspx?title=StringArrayInput http://code.msdn.microsoft.com/SQLExamples/Wiki/View.aspx?title=StringArrayInput
I used to use dynamic SQL for this, but that meant I had to dig up the code and copy it into each new app. 我曾经使用动态SQL,但这意味着我必须挖掘代码并将其复制到每个新应用程序中。 Now I don't even have to think about it.
现在我甚至不用考虑它。
A dynamic IN clause means either: 动态IN子句意味着:
DECLARE @SQL NVARCHAR(4000)
SET @SQL = 'SELECT * FROM tbl_test t
WHERE t.code IN (@string_param)
BEGIN
EXEC sp_executesql @SQL N'@string_param VARCHAR(100)', @string
END
Mind that sp_executesql
is 2005+, and preferred because it will cache the query plan. 请注意,
sp_executesql
是2005+,并且首选,因为它将缓存查询计划。 Read The Curse and Blessings of Dynamic SQL for more detail, but be aware of SQL injection attacks . 阅读动态SQL的诅咒和祝福更多细节,但要注意SQL注入攻击 。
Create a User Defined Function that takes the string as input and returns a table: 创建一个用户定义的函数,它将字符串作为输入并返回一个表:
create function [dbo].[f_SplitString] (@str as varchar (1000))
returns @t table (value varchar (50))
etc...
Then adjust your Select statement: 然后调整Select语句:
select * from tbl_test
where tbl_test.code in (select value from f_SplitString(@string))
It think the easiest way to do it, will be, dynamic SQL generation: 它认为最简单的方法就是动态SQL生成:
// assuming select is a SqlCommand
string[] values = "A,B,C,D,E,F".Split(',');
StringBuilder query = new StringBuilder();
query.Append("select * from tbl_test where tbl_test.code in (");
int i = 0;
foreach (string value in values) {
string paramName = "@p" + i++;
query.Append(paramName);
select.Parameters.AddWithValue(paramName, value);
}
query.Append(")");
select.CommandText = query.ToString();
// and then execute the select Command
Here is a function that returns a delimited String as a set of rows 这是一个函数,它将分隔的String作为一组行返回
set @string = 'A,B,C,D,E,F'
select * from tbl_test
where tbl_test.code in (select r from ftDelimitedAsTable(',',@string )
--/*----------------------------------------------------------------
Create FUNCTION [dbo].[ftDelimitedAsTable](@dlm char, @string varchar(8000))
RETURNS
--------------------------------------------------------------------------*/
/*------------------------------------------------------------------------
declare @dlm char, @string varchar(1000)
set @dlm=','; set @string='t1,t2,t3';
-- tHIS FUNCION RETUNRS IN THE ASCENDING ORDER
-- 19TH Apr 06
------------------------------------------------------------------------*/
--declare
@table_var TABLE
(id int identity(1,1),
r varchar(1000)
)
AS
BEGIN
-- a.p --
--Modified 18th Nov. 04
declare @n int,@i int
set @n=dbo.fnCountChars(@dlm,@string)+1
SET @I =1
while @I <= @N
begin
--print '@i='+convert(varchar,@i)+ ' AND INSERTING'
insert @table_var
select dbo.fsDelimitedString(@dlm,@string,@i)
set @I= @I+1
end
--PRINT '*************** ALL DONE'
if @n =1 insert @TABLE_VAR VALUES(@STRING)
--select * from @table_var
delete from @table_var where r=''
return
END
USE [QuickPickDBStaging]
GO
/****** Object: UserDefinedFunction [dbo].[fsDelimitedString] Script Date: 02/22/2010 12:31:37 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
Create function [dbo].[fsDelimitedString](
@DelimiterStr varchar(100)
,@str varchar(4000)
,@pos int=1)
returns varchar(4000)
as
/*
AP -- Dec 2003
Declare @DelimiterStr varchar(4000),@str varchar(4000) ,@pos int
set @delimiterStr = '-'
set @pos=10
set @str ='wd-1-22-333-4444-55555-666666-q-9'
*/
Begin
declare @rx varchar(4000)
set @rx=''; set @pos=@pos-1
IF DBO.fnCountChars(@DelimiterStr,@str) > 0
Begin
if dbo.fnCountChars(@delimiterStr,@str) < @pos
begin
set @rx= null
goto nulls
end
declare @i1 int,@tPos int,@ix int
set @ix=1
set @tPos=0
while @tpos <> @pos
Begin
set @ix=charindex(@DelimiterStr,@str,@ix+1)
if @ix > 0 set @tpos=@tpos+1
end
set @i1= charindex(@DelimiterStr,@str,@ix+1)
if @i1=0
set @rx=substring(@str,@ix+1,len(@str)-@ix)
else
begin
if @ix=1
set @rx=substring(@str,@ix,@i1-@ix)
else
set @rx= substring(@str, @ix+1,@i1-@ix-1)
end
-- 'print 'ix='+convert(varchar,@ix)+' @i1='+convert(varchar,@i1)+' @rx='+@rx
RETURN @RX
end
nulls:
RETURN @rx
end
You have several options: 你有几个选择:
IN
statement IN
语句中的值数量有限制 IN
or better just JOIN
statement (among other implementations I favor SQL User Defined Function to Parse a Delimited String ). IN
或更好的只是JOIN
语句(在其他实现中,我支持SQL用户定义函数来解析分隔字符串 )。 The you code would be: 你的代码是:
select tbl_test.*
from tbl_test
inner join fn_ParseText2Table(@string) x
on tbl_test.code = x.txt_value
SQL
. SQL
处理方式更好。 You could keep it really simple with built-in sql functions: 你可以使用内置的sql函数保持它非常简单:
set @string = 'A,B,C,D,E,F'
select * from tbl_test
where CHARINDEX(ISNULL(tbl_test.code, 'X'), @string) > 0
PATINDEX can be used in case you need more than one character. 如果您需要多个字符,可以使用PATINDEX。
I know this is an old question, but I thought I would post an answer to it anyway. 我知道这是一个老问题,但我想我还是会发一个答案。 I never liked passing in comma delimited string values, so I have used XML in the past and used a join statement on the xml like so:
我从不喜欢传入逗号分隔的字符串值,所以我过去使用过XML并在xml上使用了一个连接语句,如下所示:
declare @xml as xml
set @xml = '<v id="key1" /><v id="key2" /><v id="key3" />'
select
t.*
from
mytable t join @xml.nodes('/*') x(n)
on n.value('@id','varchar(50)') = t.mykey
Nothing simple. 没什么简单的。 You can write a function that will take in that list and split it apart into a table you can query against in the IN() statement.
您可以编写一个函数,该函数将接收该列表并将其拆分为可在IN()语句中查询的表。
I think, the easiest way is as below, 我想,最简单的方法如下,
Option1: 选项1:
set @string = '''A','B','C','D','E','F''' Exec ('select * from tbl_test where tbl_test.code in ('+@string+')')
Option2: 选项2:
set @string = '''A','B','C','D','E','F''' DECLARE @SQL NVARCHAR(MAX) SET @SQL='select * from tbl_test where tbl_test.code in ('+@string+')' exec sp_executesql @SQL;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.