簡體   English   中英

在ms sql服務器上的全文本搜索期間,如何處理用戶輸入?

[英]How do you handle user input during full-text search on ms sql server?

我在使用全文“包含”的ms sql服務器上有一個簡單的搜索機制。 我將搜索值作為參數傳遞給包含謂詞的對象-直接來自用戶輸入(通過asp.net網站)。 問題是我在各種情況下都會出現sql異常:-當用戶輸入兩個單詞時,例如“簡單情況”-當用戶將qoute添加到搜索值中時,例如“測試”

我已經使用如下查詢進行了測試:

declare @val nvarchar(40)
set @val = N'test"' -- or 'simple case'

select x.* FROM xx as x
where CONTAINS(x.[name], @val)

通常我會收到:“在全文搜索條件“ xxx”中,“ xxx”附近的語法錯誤。” 問題是我希望允許用戶使用“ *”,“或”和“與”條件進行高級查詢。

您如何處理用戶輸入? 你qoutename值?

在我們的應用程序中,我們對用戶輸入使用自己的簡單查詢語言:僅是操作數(帶有可選通配符的單詞或短語),運算符(AND,OR,NOT)和括號。

我們解析用戶輸入,將其分解為組成部分,並檢查語法等。

如果我們對輸入有效感到滿意,則將其重建為等效的CONTAINS條件,並將其作為參數發送給我們的搜索程序。 因為我們自己創建條件,所以我們知道它在語法上是正確的。

如果用戶輸入無效,那么我們就可以向用戶返回有意義的錯誤消息,而無需連接到數據庫。

我幾年前使用此工具構建了一個應用程序; 我所做的是前端為您提供了一個文本框來鍵入您的條款,並且它具有一個下拉菜單,可在以下幾個選項之間進行選擇:

<option selected value="AND">All of the words entered</option>
<option value="OR">Any of the words entered</option>
<option value="ALL">The exact phrase entered</option>

因此,我不希望他們鍵入“與”或“或”-我為他們這樣做。 我確實讓他們引用了一個子短語。

以下是完成此操作的一些代碼。 結果短語作為參數發送到過程; 正如上面的評論者所提到的那樣,您實際上必須這樣做以防止SQL注入。 不幸的是,該代碼是遺留的ASP VBScript,甚至不符合該語言的標准,但是也許可以給您一個想法。

 function formatContainsString (sCriteria, sANDorOR)
    dim sReturnBuf 'where we build our string
    dim sWordList 'sCriteria split
    dim lCurPos      'where we are at in sWordList
    dim bInnerQuotes ' an open quote was found
    if sCriteria = "" or sANDorOR = "" then
        formatContainsString = ""
        exit function
    end if

    ' If the passed parameter is 'ALL' then use the exact phrase typed by users
    if sANDorOR = "ALL"  then
        formatContainsString = "'"  & chr(34) & sCriteria  & chr(34) & "'"
        Exit Function
    End If

    sReturnBuf = "'"
    sWordList = split(sCriteria," ")
    for lCurPos = 0 to ubound(sWordList)
        if bInnerQuotes then 'want to pass this as a single phrase
            sReturnBuf = sReturnBuf & " " & sWordList(lCurPos)
            if right(sWordList(lCurPos),1) = chr(34) then
               sReturnBuf = left(sReturnBuf,len(sReturnBuf)-1) & "*" & chr(34)
                sReturnBuf = sReturnBuf & " " & sANDorOR & " "'phrase is over
                bInnerQuotes = False
            end if
        else        
            if left(sWordList(lCurPos),1) = chr(34) then 
                sReturnBuf = sReturnBuf & sWordList(lCurPos)
                bInnerQuotes = True
            else
                sReturnBuf = sReturnBuf & chr(34) & sWordList(lCurPos) & "*" & _ 
                    chr(34) & " " & sANDorOR & " "'quote the word
            end if
        end if
    next
    'finally, remove the last AND or OR... and append the tick
    formatContainsString = left(sReturnBuf,len(sReturnBuf)-(len(sANDorOR)+1)) _ 
        & "'"

end function

通過您得到的錯誤,我會說您沒有在查詢中使用參數。 這是非常危險的,並允許您的用戶執行sql注入。

現在,關於您的問題,我認為最好的選擇是讓您設置2種文本輸入類型,一種用於普通用戶,另一種用於高級用戶,這樣您就可以知道在哪里解析高級查詢。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM