1)我有这样的字符串:
vagalla AND suresh NOT employee OR industry
我想要的结果如下:
Name like '%vagalla%' and Name like '%suresh%' and not (Name like '%employee%' or description like '%industry4%')
2)我有这样的字符串:
vagalla OR suresh AND employee OR industry
我想要的结果如下:
(Name like '%vagalla%' or Name like '%suresh%' ) and (Name like '%employee%' or Name like '%industry%')
这是功能:
ALTER FUNCTION DBO.BOOLEANSEARCH(@SEARCHNME VARCHAR(50))
RETURNS VARCHAR(MAX)
AS
-- SELECT DBO.GETBOOLEANSEARCH ('VAGALLA SURESH')
BEGIN
DECLARE @QRY VARCHAR(MAX)
DECLARE @SEARCHSTRING VARCHAR(50)
DECLARE @START INT
DECLARE @END INT
SET @SEARCHSTRING = REPLACE(REPLACE(@SEARCHNME,'+' COLLATE LATIN1_GENERAL_CS_AI,'AND' ),'-' COLLATE LATIN1_GENERAL_CS_AI,'OR')
SELECT @START = CHARINDEX('"',@SEARCHSTRING), @END = CHARINDEX('"',REVERSE(@SEARCHSTRING))
IF( @START = 1 AND @END = 1)
BEGIN
SELECT @QRY =' COLUMNNAME = '+ SUBSTRING(@SEARCHSTRING,2,LEN(@SEARCHSTRING)-2)
END
ELSE
BEGIN
IF ( ((1>(SELECT PATINDEX('% OR %', @SEARCHSTRING COLLATE LATIN1_GENERAL_CS_AI)))
OR (1>(SELECT PATINDEX('% AND %', @SEARCHSTRING COLLATE LATIN1_GENERAL_CS_AI)))
OR (1>(SELECT PATINDEX('% NOT %', @SEARCHSTRING COLLATE LATIN1_GENERAL_CS_AI)))
) AND ((SELECT CHARINDEX('*' COLLATE LATIN1_GENERAL_CS_AI,@SEARCHSTRING))>1))
BEGIN
SELECT @QRY= ' COLUMNNAME LIKE '+ REPLACE(@SEARCHSTRING,'*', '%' )
END
ELSE IF ( ((1>(SELECT PATINDEX('% OR %', @SEARCHSTRING COLLATE LATIN1_GENERAL_CS_AI)))
OR (1>(SELECT PATINDEX('% AND %', @SEARCHSTRING COLLATE LATIN1_GENERAL_CS_AI)))
OR (1>(SELECT PATINDEX('% NOT %', @SEARCHSTRING COLLATE LATIN1_GENERAL_CS_AI)))
) AND ((SELECT CHARINDEX('*' COLLATE LATIN1_GENERAL_CS_AI,@SEARCHSTRING))<1))
BEGIN
SELECT @QRY= ' COLUMNNAME = ' + @SEARCHSTRING
END
ELSE
BEGIN
IF(1<(SELECT PATINDEX('% OR %', @SEARCHSTRING COLLATE LATIN1_GENERAL_CS_AI)))
BEGIN
SELECT @QRY =' COLUMNNAME LIKE %'+SUBSTRING(@SEARCHSTRING,1, PATINDEX('% OR %', @SEARCHSTRING COLLATE LATIN1_GENERAL_CS_AI)-1) +'%'
+' OR COLUMNNAME LIKE %'+ SUBSTRING(@SEARCHSTRING, PATINDEX('% OR %', @SEARCHSTRING COLLATE LATIN1_GENERAL_CS_AI)+3,LEN(@SEARCHSTRING))+'%'
END
ELSE IF(1<(SELECT PATINDEX('% AND %', @SEARCHSTRING COLLATE LATIN1_GENERAL_CS_AI)))
BEGIN
SELECT @QRY =' COLUMNNAME LIKE %'+SUBSTRING(@SEARCHSTRING,1, PATINDEX('% AND %', @SEARCHSTRING COLLATE LATIN1_GENERAL_CS_AI)-1) +'%'
+' AND COLUMNNAME LIKE %'+ SUBSTRING(@SEARCHSTRING, PATINDEX('% AND %', @SEARCHSTRING COLLATE LATIN1_GENERAL_CS_AI)+4,LEN(@SEARCHSTRING))+'%'
END
ELSE IF(1<(SELECT PATINDEX('% NOT %', @SEARCHSTRING COLLATE LATIN1_GENERAL_CS_AI)))
BEGIN
SELECT @QRY =' COLUMNNAME LIKE %'+SUBSTRING(@SEARCHSTRING,1, PATINDEX('% NOT %', @SEARCHSTRING COLLATE LATIN1_GENERAL_CS_AI)-1) +'%'
+' AND COLUMNNAME NOT LIKE %'+ SUBSTRING(@SEARCHSTRING, PATINDEX('% NOT %', @SEARCHSTRING COLLATE LATIN1_GENERAL_CS_AI)+4,LEN(@SEARCHSTRING))+'%'
END
---HERE I NEED TO IMPLEMENT THE OTHER CONDITION
END
END
RETURN @QRY
END
答案 0 :(得分:0)
运算符的优先级在您的示例中不清楚,因此我建议您更改规范以将括号放在输入字符串中。如果您有明确定义的优先级,我们可以在处理下一步之前使用一些代码添加括号。在那之前,你可以使用这样的东西:
DECLARE @Input VARCHAR(100)
SET @Input='(vagalla AND suresh) AND NOT (employee OR industry)'
--SET @Input='(vagalla OR suresh) AND (employee OR industry)'
DECLARE @Result VARCHAR(MAX)
DECLARE @Pos INT=0, @Prev INT, @Separator CHAR(1), @Word VARCHAR(100), @Replacement VARCHAR(350)
WHILE 1=1 BEGIN
SET @Prev=@Pos+1
DECLARE @Pos1 INT, @Pos2 INT, @Pos3 INT
SET @Pos1=ISNULL(NULLIF(CHARINDEX(' ',@Input,@Pos+1),0),LEN(@Input)+1)
SET @Pos2=ISNULL(NULLIF(CHARINDEX('(',@Input,@Pos+1),0),LEN(@Input)+1)
SET @Pos3=ISNULL(NULLIF(CHARINDEX(')',@Input,@Pos+1),0),LEN(@Input)+1)
SET @Pos=CASE
WHEN @Pos1<=@Pos2 AND @Pos1<=@Pos3 THEN @Pos1
WHEN @Pos2<=@Pos1 AND @Pos2<=@Pos3 THEN @Pos2
ELSE @Pos3
END
IF @Pos=LEN(@Input)+1 SET @Pos=0
SET @Separator=SUBSTRING(@Input,NULLIF(@Pos,0),1)
SET @Word=SUBSTRING(@Input,@Prev,ISNULL(NULLIF(@Pos,0)-1,LEN(@Input))-@Prev+1)
SET @Replacement=CASE
WHEN @Word IN ('AND','NOT','OR','') THEN @Word
ELSE 'Name LIKE ''%'+REPLACE(REPLACE(REPLACE(@Word,'''',''''''),'_','[_]'),'%','[%]')+'%'''
END
SET @Result=ISNULL(@Result,'')+@Replacement+ISNULL(@Separator,'')
--SELECT @Pos, @Separator, @Word, @Replacement, @Result
IF @Pos=0 BREAK
END
PRINT 'Input : '+@Input
PRINT 'Result: '+@Result
代码迭代搜索每个单词,考虑以下分隔符:空格,左括号,右括号。然后用LIKE表达式替换每个单词(AND,OR和NOT除外)。
在动态SQL中使用LIKE时,必须注意特殊字符,如撇号,百分比和下划线。我试图逃避那些使用REPLACE的东西,但在这种情况下正确定义字符串的长度非常重要。