2015-07-03 31 views
1

1)我有串这样的:如何为后续编写动态SQL?

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    
+3

嗨,欢迎来到Stack Overflow。你试图把自己放在一起?结果是什么?为什么你的结果不令人满意? –

+0

我仍然不确定你尝试过什么。你是否直接在sql-server中输入上述内容,或者是在你编写的代码中使用了哪个“字符串”? (如果是这样,请包含代码)当您尝试在sql-server中使用“result like”部分时发生了什么?他们没有给你想要的结果吗? –

+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 @[email protected]+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<[email protected] AND @Pos1<[email protected] THEN @Pos1 
     WHEN @Pos2<[email protected] AND @Pos2<[email protected] 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))[email protected]+1) 
    SET @Replacement=CASE 
     WHEN @Word IN ('AND','NOT','OR','') THEN @Word 
     ELSE 'Name LIKE ''%'+REPLACE(REPLACE(REPLACE(@Word,'''',''''''),'_','[_]'),'%','[%]')+'%''' 
    END 
    SET @Result=ISNULL(@Result,'')[email protected]+ISNULL(@Separator,'') 
    --SELECT @Pos, @Separator, @Word, @Replacement, @Result 
    IF @Pos=0 BREAK 
END 

PRINT 'Input : '[email protected] 
PRINT 'Result: '[email protected] 

代码反复搜索每个字,需要考虑以下分隔符:空格,左括号,右括号。然后用LIKE表达式替换每个单词(除AND,OR和NOT)。

使用LIKE动态SQL时,必须小心特殊字符,如撇号,百分比和下划线。我试图用REPLACE来逃避那些,但在这种情况下正确定义字符串的长度很重要。