![](/img/trans.png)
[英]How do you full-text search multiple criteria on left-joined tables in SQL Server?
[英]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.