[英]Filtering MySQL query only when the filter values are not empty-string, white-space or null best practice
我想在這里過濾列 A 的值,然后過濾列 B 等,但是我希望如果過濾器 valueA 只是一個空字符串,則不會發生過濾並且所有值都被接受。 如果 valueB 為空,則相同,則不會發生過濾。
這是一個通用的 mysql 查詢,我希望只在 valueA 或 valueB(包括或)具有非空、空格或空字符串的值時才進行過濾。
using (var cmd = new MySqlCommand(
" SELECT columnA, columnB etc
" FROM table" +
" WHERE columnA = '" + valueA + "' " +
" THEN BY columnB = '" + valueB + "' " +
" GROUP BY columnA" +
" LIMIT 0, 100",
connection))
@value IS NULL OR [Column] = @value
NULL
並濫用@value IS NULL OR [Column] = @value
然而,這(可能)在生產數據庫中是一件可怕的事情,因為(即使到 2021 年)我不知道任何主要RDMBS 正確處理了這種情況,你最終會得到非常非常糟糕的執行計划。在您的情況下,請執行以下操作:
String sql;
List<MySqlParameter> parameters = new List<MySqlParameter>();
{
StringBuilder sb = new StringBuilder( "SELECT columnA, columnB, FROM table" ).AppendLine();
List<String> predicates = new List<String>();
if( valueA != null )
{
predicates.Add( "columnA = @pA" );
parameters.Add( new MySqlParameter( "@pA", valueA ) );
}
if( valueB != null )
{
predicates.Add( "columnB = @pB" );
parameters.Add( new MySqlParameter( "@pB", valueB ) );
}
// etc
if( predicates.Count > 0 )
{
_ = sb.AppendLine( "WHERE" );
_ = sb.AppendLine( String.Join( " AND ", predicates ) );
}
//
_ = sb.AppendLine( "ORDER BY foo GROUP BY bar LIMIT 0, 100" );
sql = sb.ToString();
}
using( var cmd = new MySqlCommand( sql, connection ) )
{
cmd.Parameters.AddRange( parameters );
cmd.Execute...
}
您可以使用簡單的OR
邏輯,並且在 C# 端檢查空格更容易
注意使用參數化防止SQL注入
請注意使用多行字符串使查詢更易於閱讀
const string query = @"
SELECT columnA, MAX(columnB) etc
FROM table
WHERE (columnA = @valueA OR @valueA IS NULL)
AND (columnB = @valueB OR @valueB IS NULL)
GROUP BY columnA
LIMIT 0, 100;
";
using (var cmd = new MySqlCommand(query, connection))
{
cmd.Parameters.AddWithValue("@valueA", string.IsNullOrWhiteSpace(valueA) ? (object)DBNull.Value : valueA);
cmd.Parameters.AddWithValue("@valueB", string.IsNullOrWhiteSpace(valueB) ? (object)DBNull.Value : valueB);
大型表的性能可能不是很好,因此您可能需要使用完全獨立的查詢
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.