2015-08-24 32 views
3

我插入數據庫上的數據之前,包含場「全名」兩個以上的詞

在我的工具,我上傳一些文件在我的數據庫用戶和表比較字符串數據庫值我正在通過比較數據庫上的全名字段和文件上的全名字段來檢查用戶是否存在(例如,這是唯一的選擇,我無法比較ID)。

我的問題是:當它們包含兩個以上的單詞時,如何比較這些字段?

有時全名是不是爲了,例如:

------------------------------------------------- 
|  Database  ||   File   | 
------------------------------------------------- 
| Michael Yves Pierrot || Pierrot Michael Yves | 
| Martin Dupont   || Dupont Martin  | 
| Ben Jack Dupont  || Ben Dupont Jack  | 
------------------------------------------------- 

當只有兩個詞,這是好的,我用拆分的工作就像是:

public string getId() 
{ 
    string result; 
    QueryModel Query = new QueryModel(); 
    string sql = "SELECT Username_Id FROM USERNAME WHERE Full_name = '" 
     + Full_name.Replace("'", "''") + "'"; 
    result = Query.ExecuteCommand(sql, "int"); 
    if (result != "0") 
    { 
     string FullName2 = Full_name.Split(' ')[1] + " " + Full_name.Split(' ')[0]; 
     sql = "SELECT Username_Id FROM USERNAME WHERE Full_name = '" 
      + FullName2.Replace("'", "''") + "'"; 
     result = Query.ExecuteCommand(sql, "int"); 
    } 
    return result; 
} 

注意Query.ExecuteCommand(sql, "int");回報"0"當用戶不存在時。

所以,如果我的功能getId()返回"0"我將輸入新的用戶,如果它否則返回的東西,這意味着用戶存在,並且將返回Username_Id

人有一個想法?

謝謝。

+0

也許使用'%'運算符? – user1666620

+0

一個指標如果相同可以是字符串的長度。 – lad2025

回答

5

你可以做壞事像下面的(不好的,因爲潛在的性能成本):

SELECT Username_Id 
FROM USERNAME 
WHERE Full_name LIKE '%Michael%' AND Full_name LIKE '%Pierrot%' 

的「%」運算符是通配符。 https://msdn.microsoft.com/en-us/library/ms189454.aspx

我會參數化您的查詢,以防止SQL注入。

+0

謝謝。就注射而言,我正在開發一種內部工具,我不必擔心這一點! – ben

+1

@aBennouna參數化查詢比防止SQL注入具有更多優勢。它們還允許查詢計劃緩存,因此不必在每次執行時都編譯查詢。它也是更強類型,並避免意外截斷,因爲您可以指定長度。因此,即使您的系統不易受黑客攻擊,您也應該使用參數化查詢來確保準確性和性能。 – GarethD

1

感謝@ user1666620我已經修改了我的功能,以及新的代碼是:

public string getId() 
{ 
    string result; 
    QueryModel Query = new QueryModel(); 
    string[] fullName = Full_name.Replace("'", "''").Split(' '); 
    string fullNameSQL = ""; 
    for (int i = 0; i < fullName.Count() - 1; i++) 
    { 
     string fn = "Full_Name LIKE '%" + fullName[i] + "%' "; 
     fullNameSQL = (fullNameSQL == "") ? fn : fullNameSQL + " AND " + fn; 
    } 
    string sql = "SELECT Username_Id FROM USERNAME WHERE " + fullNameSQL; 
    result = Query.ExecuteCommand(sql, "int"); 
    return result; 
} 
1

這將返回所有部件拆分,並按照字母順序重新串聯。你可以使用它來直接在你的比較中使用它

DECLARE @tbl TABLE(FullName VARCHAR(100)); 
INSERT INTO @tbl VALUES('Michael Yves Pierrot'),('Michael Pierrot Yves'),('Martin Dupon'),('Dupont Martin'),('Ben Jack Dupont'),('Ben Dupont Jack'); 

WITH 
NamesSplitByXML AS 
(
    SELECT FullName 
      ,ROW_NUMBER() OVER(ORDER BY FullName) AS inx 
      ,CAST('<root><r>' + REPLACE(tbl.FullName,' ','</r><r>') + '</r></root>' AS XML) AS NameAsXml 
    FROM @tbl AS tbl 
) 
,SortedList AS 
(
    SELECT inx, ROW_NUMBER() OVER(ORDER BY inx,x.y.value('.','varchar(max)')) AS inx2, FullName,x.y.value('.','varchar(max)') AS NamePart 
    FROM NamesSplitByXML 
    CROSS APPLY NameAsXml.nodes('/root/r') AS x(y) 
) 
,DistinctInx AS 
(
    SELECT DISTINCT inx,FullName FROM SortedList 
) 
SELECT DistinctInx.inx,FullName,ConcatAlphabetical.SortedName 
FROM DistinctInx 
CROSS APPLY 
(
    SELECT STUFF(
    (
     SELECT TOP 100 PERCENT ' ' + NamePart 
     FROM SortedList WHERE DistinctInx.inx=SortedList.inx 
     ORDER BY inx2 
     FOR XML PATH(''),TYPE 
    ).value('.','varchar(max)'),1,1,'') 
) AS ConcatAlphabetical(SortedName) 
+0

@aBennouna,對不起,因爲已經有一個被接受的答案,但我花了相當一段時間在這個(我喜歡棘手的SQL黑客!),我只是好奇,如果你看看這個。它會爲你工作嗎? – Shnugo

+0

對不起@Shnugo我剛剛看到你的答案,我已經測試過它,它的工作原理!謝謝;-) – ben

+0

@aBennouna,thx,很高興聽到這個...我的方法的一個優點是,如果你填寫較小的部分,LIKE搜索可能很容易返回錯誤的結果,其他名稱也可能包含這些部分。如果你堅持LIKE的方式,你應該考慮添加空格:LIKE「%pierre%」。這確保不會找到部分名稱... – Shnugo