这是一个简单的问题,我似乎无法想出解决方案。
我在我的存储过程中定义了这个:
@communityDesc varchar(255) = NULL
@communityDesc是" aaa,bbb,ccc"
在我的实际查询中,我尝试使用IN
WHERE AREA IN (@communityDesc)
但这不起作用,因为我的逗号位于字符串内而不是像这样#34; aaa"," bbb"," ccc"
所以我的问题是,我能对@communityDesc做些什么,所以它可以用我的IN语句,比如重新格式化字符串?
答案 0 :(得分:4)
使用此变量的最简单方法是:
SELECT *
FROM something
WHERE ',' + @communityDesc + ',' Like '%,' + AREA + ',%'
这是针对tsql,因为oracle使用||
来连接字符串
答案 1 :(得分:3)
In
仅适用于值集,而不适用于字符串中的字符。要从技术上回答你的问题,你可以做到这一点的唯一方法是创建一组代表三个值'aaa','bbb'和&的值。 'ccc'然后将这三个值放入一个表(Temp Table或表变量(在SQL Server中)中),然后针对该组值执行IN(对于表:
declare @Vals table (value varchar(20))
insert @vals(Value) Values('aaa')
insert @vals(Value) Values('bbb')
insert @vals(Value) Values('ccc')
select * from SomeOtherTable
Where SomeColumn IN (Select value from @vals)
要创建集合,您需要创建一个空的临时表或表变量来保存这组值,将逗号分隔的字符串解析为单个值,并将这些单独的值输入临时表或表变量。
虽然您没有说,如果您使用的是SQL Server,以下是SQL Server用户定义函数(UDF),它将解析分隔的字符串并返回一个表,每个分隔值都有一行:
如果您创建UDF,那么您将按如下方式使用它:
select * from SomeOtherTable
Where SomeColumn IN
(Select sVal from
dbo.ParseSTring(@communityDesc, ','))
/****** Object: UserDefinedFunction [dbo].[ParseString]
Script Date: 4/8/2016 1:53:00 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER FUNCTION [dbo].[ParseString] (@S Text, @delim VarChar(5))
Returns @tOut Table
(ValNum Integer Identity Primary Key,
sVal VarChar(8000))
As
Begin
Declare @dLLen TinyInt -- Length of delimiter
Declare @sWin VarChar(8000)-- Will Contain Window into text string
Declare @wLen Integer -- Length of Window
Declare @wLast TinyInt -- Boolean to indicate processing Last Window
Declare @wPos Integer -- Start Position of Window within Text String
Declare @sVal VarChar(8000)-- String Data to insert into output Table
Declare @BtchSiz Integer -- Maximum Size of Window
Set @BtchSiz = 7900 -- (Reset to smaller values to test routine)
Declare @dPos Integer -- Position within Window of next Delimiter
Declare @Strt Integer -- Start Position of each data value in Window
-- --------------------------------------------------------------
-- ---------------------------
If @delim is Null Set @delim = '|'
If DataLength(@S) = 0 Or
Substring(@S, 1, @BtchSiz) = @delim Return
-- ---------------------------
Select @dLLen = Len(@delim),
@Strt = 1, @wPos = 1,
@sWin = Substring(@S, 1, @BtchSiz)
Select @wLen = Len(@sWin),
@wLast = Case When Len(@sWin) = @BtchSiz
Then 0 Else 1 End,
@dPos = CharIndex(@delim, @sWin, @Strt)
-- ----------------------------
While @Strt <= @wLen
Begin
If @dPos = 0 Begin -- No More delimiters in window
If @wLast = 1 Set @dPos = @wLen + 1
Else Begin
Set @wPos = @wPos + @Strt - 1
Set @sWin = Substring(@S, @wPos, @BtchSiz)
-- -------------------------------------
Select @wLen = Len(@sWin), @Strt = 1,
@wLast = Case When Len(@sWin) = @BtchSiz
Then 0 Else 1 End,
@dPos = CharIndex(@delim, @sWin, 1)
If @dPos = 0 Set @dPos = @wLen + 1
End
End
-- -------------------------------
Set @sVal = LTrim(Substring(@sWin, @Strt, @dPos - @Strt))
Insert @tOut (sVal) Values (@sVal)
-- -------------------------------
-- Move @Strt to char after last delimiter
Set @Strt = @dPos + @dLLen
Set @dPos = CharIndex(@delim, @sWin, @Strt)
End
Return
End
答案 2 :(得分:2)
您可以使用here提供的拆分功能拆分字符串。该函数返回一个包含单个列的表,用于保存您的标记(即'aaa','bbb'...)。
您的查询应如下所示:
-- get the splits
SELECT Name INTO #someTemp
FROM dbo.splitstring(@communityDesc)
-- get data where area in within description
SELECT 1
FROM yourTable T
WHERE EXISTS (SELECT 1 FROM #someTemp tmp WHERE T.Area = tmp.Name)
答案 3 :(得分:2)
另一种方法是使用CHARINDEX()。但是,在WHERE子句中使用函数会降低性能。
WHERE CHARINDEX(','+area+',',','+@CommunityDec+',')> 0
如果区域字段总是3个字母,则可以简化此操作。
WHERE CHARINDEX(area,@CommunityDec)> 0
这是一个快速的解决方案,但也是一个止损。更好的解决方案是更改字符串查找方法以构建一个表,每个搜索条件使用一行并使用JOIN或子查询。
答案 4 :(得分:2)
首先你最需要创建一个函数来分割字符串,比如这段代码
CREATE FUNCTION dbo.splitstring ( @stringToSplit VARCHAR(MAX) )
RETURNS
@returnList TABLE ([Name] [nvarchar] (500))
AS
BEGIN
DECLARE @name NVARCHAR(255)
DECLARE @pos INT
WHILE CHARINDEX(',', @stringToSplit) > 0
BEGIN
SELECT @pos = CHARINDEX(',', @stringToSplit)
SELECT @name = SUBSTRING(@stringToSplit, 1, @pos-1)
INSERT INTO @returnList
SELECT @name
SELECT @stringToSplit = SUBSTRING(@stringToSplit, @pos+1, LEN(@stringToSplit)-@pos)
END
INSERT INTO @returnList
SELECT @stringToSplit
RETURN
END
那么你可以使用这个函数就是你的查询
WHERE AREA IN (dbo.splitstring(@communityDesc))
答案 5 :(得分:1)
您可以使用XML简单地拆分此csv,并使用它来过滤查询。无需在此处使用用户定义的函数或@Table_Valiable或#Temp_Table。
DECLARE @xml as xml,@communityDesc varchar(255) = 'aaa,bbb,ccc'
SET @xml = cast(('<X>'+replace(@communityDesc,',' ,'</X><X>')+'</X>') as xml)
SELECT * FROM TABLE1
WHERE AREA IN (
SELECT N.value('.', 'varchar(10)') as value FROM @xml.nodes('X') as T(N)
)
如果在进一步处理中需要此拆分值,则可以将其插入#table_Variable或#Temp_Table并使用它们。