SQL存储过程LIKE

时间:2016-04-08 20:36:11

标签: sql

这是一个简单的问题,我似乎无法想出解决方案。

我在我的存储过程中定义了这个:

@communityDesc varchar(255) = NULL

@communityDesc是" aaa,bbb,ccc"

在我的实际查询中,我尝试使用IN

WHERE AREA IN (@communityDesc)

但这不起作用,因为我的逗号位于字符串内而不是像这样#34; aaa"," bbb"," ccc"

所以我的问题是,我能对@communityDesc做些什么,所以它可以用我的IN语句,比如重新格式化字符串?

6 个答案:

答案 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并使用它们。