Entwickler-Ecke

Datenbanken (inkl. ADO.NET) - SqlCommand Parameter Problem


hier0 - Mi 09.02.11 15:51
Titel: SqlCommand Parameter Problem
Hallo zusammen,

ich habe folgendes Problem bei der Erstellung einer Datenbankklasse, genauer gesagt bei der Definition der Parameter für den Query.

Hier mein Code:

Funktioniert nicht
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
 
cmd = new SqlCommand();
cmd.CommandText = "SELECT TOP @Top license, product, duration, amount FROM -DataBase- WHERE product = 'TBD' AND amount = @Amount AND duration = @Duration AND sr_id IS NULL";

                SqlParameter prmProduct = new SqlParameter("@Product", SqlDbType.VarChar, 100);
                    prmProduct.Value = product;
                SqlParameter prmAmount = new SqlParameter("@Amount", SqlDbType.Int);
                    prmAmount.Value = amount;
                SqlParameter prmDuration = new SqlParameter("@Duration", SqlDbType.Int);
                    prmDuration.Value = duration;
                SqlParameter prmTop = new SqlParameter("@Top", SqlDbType.Int);
                    prmTop.Value = top;

                cmd.Parameters.Add(prmProduct);
                cmd.Parameters.Add(prmAmount);
                cmd.Parameters.Add(prmDuration);
                cmd.Parameters.Add(prmTop);


Zu Testzwecken habe ich das ganze auch mal ohne Parameter ausprobiert:


Funktioniert
1:
2:
cmd.CommandText = "SELECT TOP "+top+" license, product, duration, amount FROM -DataBase- WHERE product = 'TBD' AND amount = "
                           + amount + " AND duration = " + duration +" AND sr_id IS NULL";


Da zweites Funktioniert muss der Fehler mMn in der Parameterdefinition sein.

Bin für jede Hilfe sehr Dankbar.
Mit freundlichen Grüßen

P.S. Product = 'TBD' als Platzhalter, die realen Daten sind noch nicht vorhanden.

Moderiert von user profile iconChristian S.: Code- durch C#-Tags ersetzt
Moderiert von user profile iconChristian S.: Topic aus C# - Die Sprache verschoben am Mi 09.02.2011 um 15:11


Christian S. - Mi 09.02.11 16:12

Und wie ist die Fehlerbeschrreibung? :-)


bakachan - Mi 09.02.11 16:30

Ich weiss zwar grad nicht aus dem Stehgreif ob das zu nem Fehler führt aber du fügst einen Parameter (@Product) zum command hinzu verwendest ihn aber nirgendwo (du hast direkt im cmd 'TBD' stehen anstelle des Parameters)


Th69 - Mi 09.02.11 16:33

Hallo,

die Parameter gelten nur für die WHERE-Klausel, nicht für andere Angaben im SQL-Befehl, d.h. den @TOP-Parameter mußt du dann doch per String-Konkatenation zusammenbauen:

C#-Quelltext
1:
cmd.CommandText = "SELECT TOP " + top + " ... ";                    

(TOP ist ja kein Datenbankfeld!)


hier0 - Mi 09.02.11 16:56

Vielen Dank für die vielen schnellen Antworten.

ich habe den Top Parameter ersetzt (auch schon komplett weggelassen) und die Definition hierfür sowie für den unbenutzten Product Parameter auskommentiert.

Leider funktioniert das Ganze immer noch nicht.

Eine Fehlermeldung erhalte ich nicht, lediglich meine DataTable

Quelltext
1:
2:
adapter = new SqlDataAdapter(cmd.CommandText, conn);
adapter.Fill(result);
bleibt leer.


bakachan - Mi 09.02.11 17:08

user profile iconhier0 hat folgendes geschrieben Zum zitierten Posting springen:

P.S. Product = 'TBD' als Platzhalter, die realen Daten sind noch nicht vorhanden.


Gibt überhaupt Daten in der Tabelle die die Bedingungen erfüllen ?


Th69 - Mi 09.02.11 17:09

Laß dir mal den Rückgabewert von Fill ausgeben:

C#-Quelltext
1:
int nCount = adapter.Fill(result);                    

Vllt. liefert deine SQL-Query wirklich keinen Datensatz, d.h. deine Parameter sind falsch?

P.S. Um deinen SQLCommand mit Parametern benutzen zu können, mußt du aber auch folgenden Konstruktor benutzen:

C#-Quelltext
1:
adapter = new SqlDataAdapter(cmd);                    


hier0 - Mi 09.02.11 17:14

user profile iconbakachan hat folgendes geschrieben Zum zitierten Posting springen:
user profile iconhier0 hat folgendes geschrieben Zum zitierten Posting springen:

P.S. Product = 'TBD' als Platzhalter, die realen Daten sind noch nicht vorhanden.


Gibt überhaupt Daten in der Tabelle die die Bedingungen erfüllen ?


Ja, die Datensätze haben allerdings zur Zeit alle das Product = TBD (to be defined).

Wie gesagt erhalte ich mit der 'unschönen' Variante ohne Parameter eine Ergebniszeile und kann diese auch ohne Probleme weiterverarbeiten, während die DataTable bei der 'sauberen' Variante einfach leer bleibt. (Es gibt NullPointerExceptions wenn ich versuche auf die 1. (bzw 0.) Reihe der DataTable zuzugreifen.


hier0 - Mi 09.02.11 17:28

user profile iconTh69 hat folgendes geschrieben Zum zitierten Posting springen:
Laß dir mal den Rückgabewert von Fill ausgeben:

C#-Quelltext
1:
int nCount = adapter.Fill(result);                    

Vllt. liefert deine SQL-Query wirklich keinen Datensatz, d.h. deine Parameter sind falsch?

P.S. Um deinen SQLCommand mit Parametern benutzen zu können, mußt du aber auch folgenden Konstruktor benutzen:

C#-Quelltext
1:
adapter = new SqlDataAdapter(cmd);                    


Ich habe mir nCount ausgeben lassen, wie ich gedacht habe ist dieser (bei völlig identischen Formulareingaben) mit Parameter-Query 0 und mit String-Query 1
(Es gibt zur Zeit je einen Datensatz für die verschiedenen Kombinationen der Parameter)

Kann das Problem evtl an den Datentypen der Parameter liegen?

Der Methode weird ein Strings und sonst Integers übergeben, deckt sich das mit den SqlDbType.VarChar und SqlDbType.Int oder müssen diese noch Konvertiert werden?

Nochmals herzlichen Dank für die Hilfe


bakachan - Mi 09.02.11 17:43

Mal mal die Size bei deinem VarChar-Parameter weg.


hier0 - Mi 09.02.11 18:04

Hi nochmal

ich habe meinen Code folgendermaßen geändert, nun funktioniert alles wunderbar.


C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
cmd.Parameters.Add("@Product", SqlDbType.VarChar).Value = product;
                cmd.Parameters.Add("@Amount", SqlDbType.Int).Value = amount;
                cmd.Parameters.Add("@Duration", SqlDbType.Int).Value = duration;
                cmd.Parameters.Add("@Top", SqlDbType.Int).Value = top;
 DataSet data = new DataSet();
                new SqlDataAdapter(cmd).Fill(data);
                result = data.Tables[0];


Vielen Dank nochmal an alle die sich hier mitbeteiligt haben.

Moderiert von user profile iconChristian S.: Code- durch C#-Tags ersetzt