匹配用作撇號的左右單引號
我有四列包含名稱,並希望
LIKE
在 Microsoft SQL Server 環境中使用搜尋這些名稱。複雜之處在於名稱可能包括左右單引號/帶角度的撇號(即
‘
和’
,char(145)
和char(146)
分別),這應該匹配一個直撇號(即'
,char(39)
)執行以下操作非常慢:
SELECT person_id FROM person WHERE REPLACE( REPLACE( person_name, CHAR(145), CHAR(39) ), CHAR(146), CHAR(39) ) LIKE '{USER_INPUT}'
正如在 Stack Overflow 上SQL 替換語句太慢中解釋的那樣,這是因為使用
REPLACE
使語句不可分割。有沒有一種方法可以讓 SQL Server 以更好的方式處理這種情況?
已提出的一種解決方案是讓應用程序生成一個“可搜尋”值,該值連接所有欄位(
person_name
、person_surname
、person_nickname
等)並在編輯時轉換有問題的字元。這可以被有效地索引和搜尋。與實現像 Lucene 這樣的完整 NoSQL 解決方案相比,將這些數據儲存在單獨的 SQL 表/列中需要更少的應用程序重寫。上面的例子是一個簡化:查詢並沒有像我上面解釋的那樣建構,我們確實實現了 SQL 注入(和其他)保護。
問題是如何用表數據中的直撇號替換帶角度的撇號。澄清:
- 使用者供應
O‘Malley
- 這應該匹配兩者O‘Malley
或O'Malley
- 使用者供應
O'Malley
- 這應該匹配兩者O‘Malley
或O'Malley
我們需要替換的是 SQL 數據,而不是使用者的輸入。我們可以在通過應用程序的過程中轉換使用者輸入,以便如果他們輸入有角度的撇號,我們在傳遞給 SQL 之前將它們更改為簡單的撇號。這是我們需要標準化的 SQL 中的數據。
不幸的是,數據必須作為正確的尖括號保留在數據庫中,但是當我們進行搜尋時,我們需要將它們全部與直撇號進行匹配。
處理您的問題(並避免 SQL 注入)的最佳方法是將使用者輸入作為變數傳遞。由於您使用的是 a
LIKE
您可以執行以下操作:CREATE TABLE #person (person_name nvarchar(50)) INSERT INTO #person VALUES (N'Bob'),(N'Bo''b'),(N'Bo‘b'),(N'Bo’b'),(N'Bo#b'),(N'Bo^b') DECLARE @user_input nvarchar(50) = 'Bo’b' SET @user_input = REPLACE( REPLACE( REPLACE(@user_input, N'‘', N''''), N'’', N''''), N'''', N'[‘’'']') -- @user_input now == Bo[‘’']b SELECT person_name FROM #person WHERE person_name LIKE @user_input
基本上,這用單一類型(’)替換了所有不同的 ‘,然後放入
$$ $$的周圍所有三個,以便他們習慣於
LIKE
。