Entwickler-Ecke

C# - Die Sprache - SQL-Where-Bedingung per Code zusammen bauen


mindhunter - Mi 03.11.21 15:11
Titel: SQL-Where-Bedingung per Code zusammen bauen
Hallo,

ich möchte eine SQL-Bedingung per Code aufbauen. Für die Where-Bedingung prüfe ich in 5 Textboxen deren Inhalt und damit soll die Where-Bedingung aufgebaut werden. Jetzt kann es aber sein, dass eine Textbox leer ist und somit nicht in die Bedingung aufgenommen werden darf. Mein Problem ist das AND in der Where-Bedingung, das abhängig von dem Inhalt der Textbox mit aufgenommen werden muss!
Mit der If-Bedingung komme ich nicht wirklich weiter!

SQL-Anweisung
1:
2:
3:
4:
5:
6:
7:
SELECT * FROM [table] WHERE Test1 = '1' AND Test2 = '2' AND Test3='3'
-- oder
SELECT * FROM [table] WHERE Test2 = '2' AND Test3='3'
-- oder
SELECT * FROM [table] WHERE Test1 = '1' AND Test3='3'
-- oder
SELECT * FROM [table] WHERE Test1 = '1'



Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
strSQL = "SELECT * FROM [table] WHERE "

if (textBox1.Text != null && !string.IsNullOrEmpty(textBox1.Text))
{
    string s1 = textBox1.Text.ToString();
    strSQL = strSQL + "userid = '" + s1;
}
if (textBox2.Text != null && !string.IsNullOrEmpty(textBox2.Text))
{
    string s2 = textBox1.Text.ToString();
    strSQL = strSQL + "userid = '" + s2;
}
if (textBo3.Text != null && !string.IsNullOrEmpty(textBox3.Text))
{
    string s3 = textBox3.Text.ToString();
    strSQL = strSQL + "userid = '" + s3;
}


Moderiert von user profile iconTh69: C#- durch SQL-Tags ersetzt


Th69 - Mi 03.11.21 16:39

Hallo,

leider ist dein Code doppelt schlecht:
- zu viel mehrfacher (fast gleicher) Code
- SQL-Strings sollten mittels Datenbank-Parameter aufgebaut werden (s. z.B. [Artikelserie] SQL: Parameter von Befehlen [https://mycsharp.de/forum/threads/66704/artikelserie-sql-parameter-von-befehlen] "Lösungsweg")

Desweiteren würde dein Code bisher, wenn alle Texte leer sind, ein ungültiges SQL-Kommando erzeugen.

Besser ist es, du setzt die Bedingung getrennt zusammen, prüfst dann ob sie nicht leer ist und erzeugst dann das komplette SQL-Kommando.
Und für den eigentlichen Code erzeugst du am besten eine Liste der 5 Texte und prüfst in einer Schleife jeweils ob sie nicht leer sind:

C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
string condition = String.Empty;
int n = 0;
foreach (string sValue in values)
{
  if (!String.IsNullOrEmpty(sValue)) // die zusätzliche Abfrage auf null ist überflüssig
  {
     if (condition != String.Empty)
       condition += " AND "// soll hier nicht ein OR hin???

     n++;
     string sValueParam = "@value" + n;
     condition += "userid = " + sValueParam;

     cmd.Parameters.AddWithValue(sValueParam, sValue);
  }
}

if (!String.IsNullOrEmpty(condition))
{
  // ... SQL-Kommando zusammenbauen und senden
}


Ralf Jansen - Mi 03.11.21 17:32

Dein Beispiel ist etwas uneindeutig da du im SQL von verschiedenen Spalten ausgehst dein Codebeispiel aber scheinbar immer die userid Spalte referenziert.

Wenn es immer die gleiche Spalte ist macht AND aber keinen Sinn. In einer Spalte ist immer ein Wert da kann nicht gleichzeitig die id '1' und '2' drin sein. Möchtest du vielleicht eher ODER?
Dann hilft die IN Function in SQL die dann logisch auch einem ODER entspricht.


SQL-Anweisung
1:
SELECT * FROM [table] WHERE userid IN ('1''2''3')                    

Wenn doch AND und verschiedenen Spalten gemeint sind könntest du die Werte aus den Textboxen und den Namen der Zielspalte in einem Dictionary zwischenspeichern und dann in einer anderen Methode wie von user profile iconTh69 gezeigt dann aus diesem Dictionary die Where Klausel generieren. Da müßtest du dich dann nicht um null Werte kümmern die solltest du erst gar nicht in das Dictionary schreiben.


icho2099 - Do 04.11.21 08:13

ich mach das so wenn es eine Folge von AND ist:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
sql.add('select * from table ');
sql.add('where (1=1)');

if edit1.text <> '' then begin
  sql.add('AND (field1 = :p01');
  parambyname('p01').asstring := edit1.text;
end;

if edit2.text <> '' then begin
  sql.add('AND (field2 = :p02');
  parambyname('p02').asstring := edit2.text;
end;