2015-07-03 29 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來逃避那些,但在這種情況下正確定義字符串的長度很重要。