簡體   English   中英

Sql/Dapper:如何在 WHERE 子句中為值數組執行 LIKE?

[英]Sql/Dapper: How do perform LIKE in WHERE clause for array of values?

我有一張桌子,里面有很多員工,每個人都有一個姓名列,上面有他們的全名。

然后,我想在搜索人員時執行與此類似的查詢:

SELECT * FROM Employees WHERE Name LIKE '%' + @value1 + '%' AND Name LIKE '%' + @value2 +'%' AND so forth...

對於任意值數組。

我的 Dapper 代碼看起來像這樣:

public IEnumerable<Employee> Search(string[] words)
{
  using var connection = CreateConnection();
  connection.Query<Employee>("SELECT * etc.", words);
}

是否有任何方法可以使用 SQL 來執行此操作,而無需使用字符串連接,以及隨后的 SQL 注入攻擊的風險?

警告:我不知道 Dapper 實際上是如何將數組傳遞給查詢的,這限制了我解決此問題的創意:-D

而且:不幸的是,改變表結構是不可能的。 而且我寧願避免讓每個人都進入.Net memory 並在那里進行過濾。

是否有任何方法可以使用 SQL 來執行此操作,而無需使用字符串連接,以及隨后的 SQL 注入攻擊的風險?

因為 where 條件的集合不是固定的,您需要動態構建查詢。 但這並不意味着您不能參數化查詢,您只需在構建查詢的同時構建參數列表。 每次列表中的一個單詞添加到條件並添加一個參數。

由於 Dapper 不直接包含任何需要收集DbParameter的內容,請考慮使用 ADO.NET 獲取IDataReader ,然后獲取 Dappter 的

IEnumerable<T> Parse<T>(this IDataReader reader)

用於映射。

這樣的建設者將非常粗略

var n = 0;
for (criterion in cirteria) {
  var cond = $"{crition.column} like @p{n}";
  var p = new SqlPatameter($"@p{n}", $"%{crition.value}%";
  conditions.Add(cond);
  cmd.Parameters.Add(p);
}

var sql = "select whetever from table where " + String.Join(" and ", conditions);
cmd.CommandText = sql;
var reader  = await cmd.ExecuteReaderAsync();
var res = reader.Parse<TResult>();

出於性能原因,最好將其作為基於集合的操作來執行。

您可以將數據表作為表值參數傳遞,然后以LIKE作為條件加入該數據表。 在這種情況下,您希望所有值都匹配,因此您需要一點關系除法。

首先創建您的表類型:

CREATE TYPE dbo.StringList AS TABLE (str varchar(100) NOT NULL);

您的 SQL 如下:

SELECT *
FROM Employees e
WHERE NOT EXISTS (SELECT 1
    FROM @words w
    WHERE e.Name NOT LIKE '%' + w.str + '%' ESCAPE '/'   -- if you want to escape wildcards you need to add ESCAPE
);

然后你通過列表如下:

public IEnumerable<Employee> Search(string[] words)
{
  var table = new DataTable{ Columns = {
    {"str", typeof(string)},
  } };
  foreach (var word in words)
    table.Rows.Add(SqlLikeEscape(word));    // make a function that escapes wildcards

  using var connection = CreateConnection();
  return connection.Query<Employee>(yourQueryHere, new
    {
      words = table.AsTableValuedParameter("dbo.StringList"),
    });
}

暫無
暫無

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

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