Sql-Server

匹配用作撇號的左右單引號

  • February 18, 2022

我有四列包含名稱,並希望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_nameperson_surnameperson_nickname等)並在編輯時轉換有問題的字元。這可以被有效地索引和搜尋。與實現像 Lucene 這樣的完整 NoSQL 解決方案相比,將這些數據儲存在單獨的 SQL 表/列中需要更少的應用程序重寫。

上面的例子是一個簡化:查詢並沒有像我上面解釋的那樣建構,我們確實實現了 SQL 注入(和其他)保護。

問題是如何用表數據中的直撇號替換帶角度的撇號。澄清:

  • 使用者供應O‘Malley- 這應該匹配兩者O‘MalleyO'Malley
  • 使用者供應O'Malley- 這應該匹配兩者O‘MalleyO'Malley

我們需要替換的是 SQL 數據,而不是使用者的輸入。我們可以在通過應用程序的過程中轉換使用者輸入,以便如果他們輸入有角度的撇號,我們在傳遞給 SQL 之前將它們更改為簡單的撇號。這是我們需要標準化的 SQL 中的數據。

不幸的是,數據必須作為正確的尖括號保留在數據庫中,但是當我們進行搜尋時,我們需要將它們全部與直撇號進行匹配。

處理您的問題(並避免 SQL 注入)的最佳方法是將使用者輸入作為變數傳遞。由於您使用的是 aLIKE您可以執行以下操作:

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

引用自:https://dba.stackexchange.com/questions/150899