Czy istnieje lepszy sposób na dynamiczne tworzenie klauzuli SQL WHERE niż używanie 1 = 1 na jej początku?


110

Buduję jakąś SQL kwerendy w języku C #. Będzie się różnić w zależności od niektórych warunków przechowywanych jako zmienne w kodzie.

string Query="SELECT * FROM Table1 WHERE 1=1 ";
if (condition1) 
    Query += "AND Col1=0 ";
if (condition2) 
    Query += "AND Col2=1 ";
if (condition3) 
    Query += "AND Col3=2 ";

Działa, ale testowanie 1 = 1 nie wydaje się eleganckie. Gdybym go nie używał, musiałbym za każdym razem pamiętać i sprawdzać, czy słowo kluczowe „gdzie” zostało już dodane do zapytania, czy nie.

Czy jest lepsze rozwiązanie?


118
Szczerze mówiąc - ja też bym tak zrobił, ale bym użył 42 = 42;-)
fero

5
Właściwie zawsze piszę swoje zapytania w ten sposób. Ułatwia
wykomentowanie

4
@catfood Pierwszym projektem, w którym brałem udział jako stażysta, było pisanie narzędzi pomagających analizować zapytania dotyczące wydajności na naszych serwerach Sybase. Zabawnym odkryciem były setki tysięcy Select 42zapytań, które otrzymywaliśmy. (niezbyt zabawna była próba wyśledzenia źródła)
Mr.Mindor

24
If I didn't use it, I would have to remember and check every time if "where" keyword was already added or not to the query- Dlatego używasz 1 = 1. Silnik bazy danych i tak go optymalizuje, więc chociaż może wyglądać brzydko, jest to zdecydowanie najłatwiejszy sposób rozwiązania problemu.
Robert Harvey

4
Chociaż podane odpowiedzi są bardzo ładne, myślę, że Twój oryginalny kod jest najłatwiejszy do odczytania.
Uooo,

Odpowiedzi:


157

Zapisz warunki na liście:

List<string> conditions = new List<string>();

if (condition1) conditions.Add("Col1=0");
//...
if (conditions.Any())
    Query += " WHERE " + string.Join(" AND ", conditions.ToArray());

24
Dobre rozwiązanie, ale ToArray()nie jest konieczne w .NET 4, ponieważ istnieje przeciążenie, które akceptuje dowolne IEnumerable<string>.
fero

101
Jestem podekscytowany wszystkimi możliwościami iniekcji SQL, które to zapewnia.
asteri

12
@Jeff Jeśli nie zakodujesz na stałe wartości w klauzuli where, możesz po prostu mieć drugą listę z SqlParameters. Wystarczy wypełnić tę listę w tym samym czasie co listę warunków i wywołać AddRange (parameters.ToArray ()) na końcu.
Scott Chamberlain

5
@ScottChamberlain Tak, możesz też po prostu pominąć ciągi wejściowe przed umieszczeniem ich na liście. Przede wszystkim ostrzegałem przed możliwym atakiem żartobliwym humorem.
asteri

4
@Jeff jest podatny na wstrzyknięcie SQL tylko wtedy, gdy warunki obejmują dane wejściowe użytkownika (oryginalny przykład nie)
D Stanley

85

Jednym z rozwiązań jest po prostu nie pisanie zapytań ręcznie przez dołączanie ciągów. Możesz użyć ORM, takiego jak Entity Framework , a LINQ to Entities użyć funkcji, które oferuje język i struktura:

using (var dbContext = new MyDbContext())
{
    IQueryable<Table1Item> query = dbContext.Table1;

    if (condition1)
    {
        query = query.Where(c => c.Col1 == 0);
    }
    if (condition2)
    {
        query = query.Where(c => c.Col2 == 1);
    }
    if (condition3)
    {
        query = query.Where(c => c.Col3 == 2);
    }   

    PrintResults(query);
}

@vaheeds Nie rozumiem tego pytania. Oba są różnymi ORMami.
CodeCaster,

Przepraszam, szukałem, aby porównać wydajność eleganckiego z innymi ORMami i trafiłem tutaj przez google, więc pomyślałem, że wygenerowane PrintResults(query)zapytanie zostanie następnie użyte w eleganckim zapytaniu !!
vaheeds

@vaheeds w porządku, ale niezrozumienie odpowiedzi nie gwarantuje negatywnego głosu. Gdybyś to był Ty, co przypadkowo wydarzyło się w tym samym czasie, co Twój komentarz.
CodeCaster,

Twoje prawo, to było nieporozumienie. Cierpię z powodu złej wydajności linq do jednostek w skomplikowanych zapytaniach. Głos przeciwny zrekompensowałem twoimi innymi odpowiedziami, głosem
pozytywnym

To nie jest odpowiedź na pytanie
HGMamaci

17

Trochę przesady w tym prostym przypadku, ale w przeszłości używałem kodu podobnego do tego.

Utwórz funkcję

string AddCondition(string clause, string appender, string condition)
{
    if (clause.Length <= 0)
    {
        return String.Format("WHERE {0}",condition);
    }
    return string.Format("{0} {1} {2}", clause, appender, condition);
}

Użyj tego w ten sposób

string query = "SELECT * FROM Table1 {0}";
string whereClause = string.Empty;

if (condition 1)
    whereClause = AddCondition(whereClause, "AND", "Col=1");

if (condition 2)
    whereClause = AddCondition(whereClause, "AND", "Col2=2");

string finalQuery = String.Format(query, whereClause);

W ten sposób, jeśli nie zostaną znalezione żadne warunki, nie przejmujesz się nawet ładowaniem instrukcji where w zapytaniu i oszczędzasz serwerowi sql mikrosekundę przetwarzania klauzuli junk where podczas analizowania instrukcji sql.


Nie widzę, jak to czyni go bardziej eleganckim. Z pewnością nie jest bardziej jasne, co się tutaj dzieje. Widzę użycie tej funkcji użytkowej, ale nie jest ona bardziej elegancka.
usr

oddał Ci jeden głos za
pouczenie

15

Jest jeszcze jedno rozwiązanie, które też może nie jest eleganckie, ale działa i rozwiązuje problem:

String query = "SELECT * FROM Table1";
List<string> conditions = new List<string>();
// ... fill the conditions
string joiner = " WHERE ";
foreach (string condition in conditions) {
  query += joiner + condition;
  joiner = " AND "
}

Dla:

  • pusta lista warunków, wynik będzie prosty SELECT * FROM Table1,
  • będzie to jeden warunek SELECT * FROM Table1 WHERE cond1
  • każdy kolejny warunek wygeneruje dodatkowe AND condN

6
To pozostawia zwisające, WHEREjeśli nie ma predykatów; 1 = 1 istnieje specjalnie, aby tego uniknąć.
Gaius

Więc przejdź do String query = "SELECT * FROM Table1";i string jointer = " WHERE ";?
Brendan Long

@BrendanLong W WHEREtakim razie ANDs należy umieścić między warunkami?
PenguinCoder

@PenguinCoder Trudno jest pokazać pełny kod w komentarzu. Chodziło mi o zastąpienie string joinerlinii przez string joiner = " WHERE ";i pozostawienie joiner = " AND ";linii w spokoju.
Brendan Long

@Gaius Zakładałem, że kodeksy nie są puste, ale wstawienie GDZIE do stolarza powinno załatwić sprawę. Dzięki za uwagę!
Dariusz

11

Po prostu zrób coś takiego:

using (var command = connection.CreateCommand())
{
    command.CommandText = "SELECT * FROM Table1";

    var conditions = "";
    if (condition1)
    {    
        conditions += "Col1=@val1 AND ";
        command.AddParameter("val1", 1);
    }
    if (condition2)
    {    
        conditions += "Col2=@val2 AND ";
        command.AddParameter("val2", 1);
    }
    if (condition3)
    {    
        conditions += "Col3=@val3 AND ";
        command.AddParameter("val3", 1);
    }
    if (conditions != "")
        command.CommandText += " WHERE " + conditions.Remove(conditions.Length - 5);
}

Jest bezpieczny dla iniekcji SQL i IMHO , jest całkiem czysty. Po Remove()prostu usuwa ostatnie AND;

Działa zarówno wtedy, gdy nie określono żadnych warunków, jeśli taki został ustawiony, lub jeśli ustawiono wiele.


1
Nie jestem pewien (sam nie używaj C #), ale powiedziałbym, że tak conditions != nulljest zawsze true, ponieważ inicjujesz go ""(chyba że w C # "" == null). Pewnie powinien być czek, jeśli conditionsnie jest pusty… ;-)
siegi

9

Po prostu dołącz dwie linie z tyłu.

string Query="SELECT * FROM Table1 WHERE 1=1 ";
if (condition1) Query+="AND Col1=0 ";
if (condition2) Query+="AND Col2=1 ";
if (condition3) Query+="AND Col3=2 ";
Query.Replace("1=1 AND ", "");
Query.Replace(" WHERE 1=1 ", "");

Na przykład

SELECT * FROM Table1 WHERE 1=1 AND Col1=0 AND Col2=1 AND Col3=2 

stanie się

SELECT * FROM Table1 WHERE Col1=0 AND Col2=1 AND Col3=2 

Podczas

SELECT * FROM Table1 WHERE 1=1 

stanie się

SELECT * FROM Table1

=======================================

Dzięki za wskazanie błędu tego rozwiązania:

„Może to spowodować przerwanie zapytania, jeśli z jakiegoś powodu jeden z warunków zawiera tekst„ 1 = 1 AND ”lub„ WHERE 1 = 1 ”. Może tak być w przypadku, gdy warunek zawiera podzapytanie lub próbuje sprawdzić, czy kolumna zawiera na przykład ten tekst. Może to nie jest problem w Twoim przypadku, ale pamiętaj o tym… ”

Aby pozbyć się tego problemu, musimy rozróżnić „główne” GDZIE 1 = 1 i te z podzapytania, co jest łatwe:

Po prostu uczyń „główne” GDZIE specjalnym: dodałbym znak „$”

string Query="SELECT * FROM Table1 WHERE$ 1=1 ";
if (condition1) Query+="AND Col1=0 ";
if (condition2) Query+="AND Col2=1 ";
if (condition3) Query+="AND Col3=2 ";

Następnie nadal dołącz dwie linie:

Query.Replace("WHERE$ 1=1 AND ", "WHERE ");
Query.Replace(" WHERE$ 1=1 ", "");

1
Może to spowodować przerwanie zapytania, jeśli z jakiegokolwiek powodu jeden z warunków zawiera tekst "1=1 AND "lub " WHERE 1=1 ". Może tak być w przypadku, gdy warunek zawiera podzapytanie lub na przykład próbuje sprawdzić, czy jakaś kolumna zawiera ten tekst. Może to nie jest problem w twoim przypadku, ale powinieneś o tym pamiętać…
siegi

8

Użyj tego:

string Query="SELECT * FROM Table1 WHERE ";
string QuerySub;
if (condition1) QuerySub+="AND Col1=0 ";
if (condition2) QuerySub+="AND Col2=1 ";
if (condition3) QuerySub+="AND Col3=2 ";

if (QuerySub.StartsWith("AND"))
    QuerySub = QuerySub.TrimStart("AND".ToCharArray());

Query = Query + QuerySub;

if (Query.EndsWith("WHERE "))
    Query = Query.TrimEnd("WHERE ".ToCharArray());

Ta odpowiedź zadziała i nie ma w niej nic złego, ale nie sądzę, że jest bardziej przejrzysta i prosta niż oryginalne pytanie. QuerySubMoim zdaniem wyszukiwanie ciągów znaków nie jest ani lepsze, ani gorsze niż użycie where 1=1hacka. Ale to przemyślany wkład.
catfood

3
Wystąpił błąd. Poprawiłem to. Moje zapytanie byłoby bombowe, gdyby nie było żadnego z warunków :-P Muszę jednak powiedzieć, że rozwiązania Ahmeda lub CodeCaster są dla mnie najlepszym rozwiązaniem. Przedstawiłem wam tylko alternatywę!
Anshuman

Ogólnie jest to nadal błędne. Przypuśćmy, że tak ... FROM SOMETABLE WHERE ; wtedy TrimEndfaktycznie zredukowałby to do... FROM SOMETABL . Jeśli to faktycznie był a StringBuilder(co powinno być, jeśli masz mniej więcej tyle manipulacji na łańcuchach lub więcej), możesz po prostu Query.Length -= "WHERE ".Length;.
Mark Hurd

Mark, to działa. Próbowałem tego w wielu projektach. Spróbuj, a przekonasz się, że tak!
Anshuman

8
brzydki jak diabli :) plus może stworzyć do 7 strun, jeśli dobrze policzyłem
Piotr Perak

5

Dlaczego nie skorzystać z istniejącego narzędzia do tworzenia zapytań? Coś w rodzaju Sql Kata .

Obsługuje złożone warunki, łączenia i podzapytania.

var query = new Query("Users").Where("Score", ">", 100).OrderByDesc("Score").Limit(100);

if(onlyActive)
{
   query.Where("Status", "active")
}

// or you can use the when statement

query.When(onlyActive, q => q.Where("Status", "active"))

działa z serwerem Sql, MySql i PostgreSql.


4

Najszybsze dosłowne rozwiązanie tego, o co mnie pytasz, to:

string Query="SELECT * FROM Table1";
string Conditions = "";

if (condition1) Conditions+="AND Col1=0 ";
if (condition2) Conditions+="AND Col2=1 ";
if (condition3) Conditions+="AND Col3=2 ";

if (Conditions.Length > 0) 
  Query+=" WHERE " + Conditions.Substring(3);

Nie wydaje się to eleganckie, na pewno, do czego odesłałbym Cię do zalecenia CodeCaster dotyczącego korzystania z ORM. Ale jeśli pomyślisz o tym, co to tutaj robi, naprawdę nie martwisz się „marnowaniem” 4 znaków pamięci, a komputer bardzo szybko przesuwa wskaźnik o 4 miejsca.

Jeśli masz czas, aby nauczyć się obsługi ORM, może to naprawdę się opłacić. Ale jeśli chodzi o to, jeśli starasz się, aby ten dodatkowy warunek nie dotknął bazy danych SQL, zrobi to za Ciebie.


4

Jeśli jest to SQL Server , możesz uczynić ten kod znacznie czystszym.

Zakłada to również znaną liczbę parametrów, co może być złym założeniem, gdy myślę o możliwościach.

W C # użyłbyś:

using (SqlConnection conn = new SqlConnection("connection string"))
{
    conn.Open();
    SqlCommand command = new SqlCommand()
    {
        CommandText = "dbo.sample_proc",
        Connection = conn,
        CommandType = CommandType.StoredProcedure
    };

    if (condition1)
        command.Parameters.Add(new SqlParameter("Condition1", condition1Value));
    if (condition2)
        command.Parameters.Add(new SqlParameter("Condition2", condition2Value));
    if (condition3)
        command.Parameters.Add(new SqlParameter("Condition3", condition3Value));

    IDataReader reader = command.ExecuteReader();

    while(reader.Read())
    {
    }

    conn.Close();
}

A potem po stronie SQL:

CREATE PROCEDURE dbo.sample_proc
(
    --using varchar(50) generically
    -- "= NULL" makes them all optional parameters
    @Condition1 varchar(50) = NULL
    @Condition2 varchar(50) = NULL
    @Condition3 varchar(50) = NULL
)
AS
BEGIN
    /*
    check that the value of the parameter 
    matches the related column or that the 
    parameter value was not specified.  This
    works as long as you are not querying for 
    a specific column to be null.*/
    SELECT *
    FROM SampleTable
    WHERE (Col1 = @Condition1 OR @Condition1 IS NULL)
    AND   (Col2 = @Condition2 OR @Condition2 IS NULL)
    AND   (Col3 = @Condition3 OR @Condition3 IS NULL)
    OPTION (RECOMPILE)
    --OPTION(RECOMPILE) forces the query plan to remain effectively uncached
END

Ukrywanie kolumn wewnątrz wyrazem może uniemożliwić korzystanie z indeksów, a technika ta nie jest zalecane z tego powodu tutaj .
bbsimonbb

to ciekawe znalezisko. Dzięki za te informacje. zaktualizuje
mckeejm

3

W zależności od warunku w zapytaniu może być możliwe użycie logiki boolowskiej. Coś takiego :

string Query="SELECT * FROM Table1  " +
             "WHERE (condition1 = @test1 AND Col1=0) "+
             "AND (condition2 = @test2 AND Col2=1) "+
             "AND (condition3 = @test3 AND Col3=2) ";

3

Podoba mi się płynny interfejs stringbuildera, więc stworzyłem kilka ExtensionMethods.

var query = new StringBuilder()
    .AppendLine("SELECT * FROM products")
    .AppendWhereIf(!String.IsNullOrEmpty(name), "name LIKE @name")
    .AppendWhereIf(category.HasValue, "category = @category")
    .AppendWhere("Deleted = @deleted")
    .ToString();

var p_name = GetParameter("@name", name);
var p_category = GetParameter("@category", category);
var p_deleted = GetParameter("@deleted", false);
var result = ExecuteDataTable(query, p_name, p_category, p_deleted);


// in a seperate static class for extensionmethods
public StringBuilder AppendLineIf(this StringBuilder sb, bool condition, string value)
{
    if(condition)
        sb.AppendLine(value);
    return sb;
}

public StringBuilder AppendWhereIf(this StringBuilder sb, bool condition, string value)
{
    if (condition)
        sb.AppendLineIf(condition, sb.HasWhere() ? " AND " : " WHERE " + value);
    return sb;
}

public StringBuilder AppendWhere(this StringBuilder sb, string value)
{
    sb.AppendWhereIf(true, value);
    return sb;
}

public bool HasWhere(this StringBuilder sb)
{
    var seperator = new string [] { Environment.NewLine };
    var lines = sb.ToString().Split(seperator, StringSplitOptions.None);
    return lines.Count > 0 && lines[lines.Count - 1].Contains("where", StringComparison.InvariantCultureIgnoreCase);
}

// http://stackoverflow.com/a/4217362/98491
public static bool Contains(this string source, string toCheck, StringComparison comp)
{
    return source.IndexOf(toCheck, comp) >= 0;
}

2

IMHO, myślę, że twoje podejście jest złe:

Zapytanie do bazy danych przez konkatenację stringów NIGDY nie jest dobrym pomysłem (ryzyko wstrzyknięcia SQL i kodu można łatwo zepsuć, jeśli wprowadzisz jakieś zmiany w innym miejscu).

Możesz użyć ORM (ja używam NHibernate ) lub przynajmniej użyćSqlCommand.Parameters

Jeśli absolutnie chcesz użyć konkatenacji ciągów, użyłbym a StringBuilder(jest to właściwy obiekt do konkatenacji ciągów):

var query = new StringBuilder("SELECT * FROM Table1 WHERE");
int qLength = query.Length;//if you don't want to count :D
if (Condition1) query.Append(" Col1=0 AND");
if (Condition2) query.Append(" Col2=0 AND");
....
//if no condition remove WHERE or AND from query
query.Length -= query.Length == qLength ? 6 : 4;

Jak ostatnia myśl, Where 1=1jest naprawdę brzydka, ale SQL Server i tak go zoptymalizuje.


SELECT * FROM Table1 WHERE AND Col1=0 nie wydaje się poprawne, o co chodzi w WHERE 1=1 .
Mormegil,

2

Dapper SqlBuilder to całkiem dobra opcja. Jest nawet używany w produkcji w StackOverflow.

Przeczytaj wpis na blogu Sama na ten temat .

O ile wiem, nie jest częścią żadnego pakietu Nuget, więc musisz skopiować i wkleić jego kod do swojego projektu lub pobrać źródło Dapper i skompilować projekt SqlBuilder. Tak czy inaczej, będziesz musiał również odwołać się do Dappera dla DynamicParametersklasy.


1
Nie sądzę, aby SqlBuilder firmy Dapper był zawarty w tym pakiecie.
Ronnie Overby

1

Widzę, że jest to używane przez cały czas w Oracle podczas budowania dynamicznego SQL w ramach procedur składowanych . Używam go w zapytaniach, jednocześnie eksplorując problemy z danymi, aby przyspieszyć przełączanie między różnymi filtrami danych ... Wystarczy zakomentować warunek lub łatwo dodać go z powrotem.

Uważam, że jest to dość powszechne i łatwe do zrozumienia dla kogoś przeglądającego Twój kod.


1
public static class Ext
{
    public static string addCondition(this string str, bool condition, string statement)
    {
        if (!condition)
            return str;

        return str + (!str.Contains(" WHERE ") ? " WHERE " : " ") + statement;
    }

    public static string cleanCondition(this string str)
    {
        if (!str.Contains(" WHERE "))
            return str;

        return str.Replace(" WHERE AND ", " WHERE ").Replace(" WHERE OR ", " WHERE ");
    }
}

Realizacja metodami rozszerzającymi.

    static void Main(string[] args)
    {
        string Query = "SELECT * FROM Table1";

        Query = Query.addCondition(true == false, "AND Column1 = 5")
            .addCondition(18 > 17, "AND Column2 = 7")
            .addCondition(42 == 1, "OR Column3 IN (5, 7, 9)")
            .addCondition(5 % 1 > 1 - 4, "AND Column4 = 67")
            .addCondition(Object.Equals(5, 5), "OR Column5 >= 0")
            .cleanCondition();

        Console.WriteLine(Query);
    }

PRZECIW ZBOŻU!
Ronnie Overby

Przepraszam? Co masz na myśli?
Maxim Zhukov

0

Korzystając z stringfunkcji możesz to również zrobić w ten sposób:

string Query = "select * from Table1";

if (condition1) WhereClause += " Col1 = @param1 AND "; // <---- put conditional operator at the end
if (condition2) WhereClause += " Col1 = @param2 OR ";

WhereClause = WhereClause.Trim();

if (!string.IsNullOrEmpty(WhereClause))
    Query = Query + " WHERE " + WhereClause.Remove(WhereClause.LastIndexOf(" "));
// else
// no condition meets the criteria leave the QUERY without a WHERE clause  

Osobiście uważam, że na końcu łatwo jest usunąć element (y) warunkowy (e), ponieważ jego położenie jest łatwe do przewidzenia.


0

Pomyślałem o rozwiązaniu, które, no cóż, być może jest nieco bardziej czytelne:

string query = String.Format("SELECT * FROM Table1 WHERE "
                             + "Col1 = {0} AND "
                             + "Col2 = {1} AND "
                             + "Col3 = {2}",
                            (!condition1 ? "Col1" : "0"),
                            (!condition2 ? "Col2" : "1"),
                            (!condition3 ? "Col3" : "2"));

Nie jestem tylko pewien, czy interpreter SQL zoptymalizuje również Col1 = Col1warunek (drukowany, gdy condition1jest fałszywy).


0

Oto bardziej elegancki sposób:

    private string BuildQuery()
    {
        string MethodResult = "";
        try
        {
            StringBuilder sb = new StringBuilder();

            sb.Append("SELECT * FROM Table1");

            List<string> Clauses = new List<string>();

            Clauses.Add("Col1 = 0");
            Clauses.Add("Col2 = 1");
            Clauses.Add("Col3 = 2");

            bool FirstPass = true;

            if(Clauses != null && Clauses.Count > 0)
            {
                foreach(string Clause in Clauses)
                {
                    if (FirstPass)
                    {
                        sb.Append(" WHERE ");

                        FirstPass = false;

                    }
                    else
                    {
                        sb.Append(" AND ");

                    }

                    sb.Append(Clause);

                }

            }

            MethodResult = sb.ToString();

        }
        catch //(Exception ex)
        {
            //ex.HandleException()
        }
        return MethodResult;
    }

0

Jak już powiedziano, tworzenie SQL przez konkatenację nigdy nie jest dobrym pomysłem . Nie tylko z powodu iniekcji SQL. Przede wszystkim dlatego, że jest po prostu brzydki, trudny w utrzymaniu i całkowicie niepotrzebny . Musisz uruchomić program ze śledzeniem lub debugowaniem, aby zobaczyć, jaki SQL generuje. Jeśli używasz QueryFirst (zastrzeżenie: które napisałem), nieszczęśliwa pokusa zostaje usunięta i możesz od razu zacząć to robić w SQL.

Ta strona zawiera obszerne omówienie opcji TSQL do dynamicznego dodawania predykatów wyszukiwania. Poniższa opcja jest przydatna w sytuacjach, w których chcesz pozostawić użytkownikowi wybór kombinacji predykatów wyszukiwania.

select * from table1
where (col1 = @param1 or @param1 is null)
and (col2 = @param2 or @param2 is null)
and (col3 = @param3 or @param3 is null)
OPTION (RECOMPILE)

QueryFirst daje C # null do db NULL, więc po prostu wywołujesz metodę Execute () z wartościami null, gdy jest to konieczne, i wszystko po prostu działa. <opinion> Dlaczego programiści C # są tak niechętni do robienia rzeczy w SQL, nawet jeśli jest to prostsze. Głupia myśl. </opinion>


0

W przypadku dłuższych kroków filtrowania StringBuilder jest lepszym podejściem, jak wielu twierdzi.

w twoim przypadku poszedłbym z:

StringBuilder sql = new StringBuilder();

if (condition1) 
    sql.Append("AND Col1=0 ");
if (condition2) 
    sql.Append("AND Col2=1 ");
if (condition3) 
    sql.Append("AND Col3=2 ");

string Query = "SELECT * FROM Table1 ";
if(sql.Length > 0)
 Query += string.Concat("WHERE ", sql.ToString().Substring(4)); //avoid first 4 chars, which is the 1st "AND "

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.