Laden...

Select Anweisung die mal geht und mal nicht

Erstellt von belbono vor 17 Jahren Letzter Beitrag vor 17 Jahren 2.107 Views
B
belbono Themenstarter:in
25 Beiträge seit 2006
vor 17 Jahren
Select Anweisung die mal geht und mal nicht

Hallo,

sorry für das nicht-suchen, aber mir fällt weder ein Suchbegriff dafür ein noch ein vernünftiger Threadname.

Also es ist eine ganz kuriose Sache:

public static DataSet getTransaktDates(DateTime from, DateTime to)
	{
        string strfrom = from.ToString("yyyy-MM-dd");
        string strto = to.ToString("yyyy-MM-dd");
		SqlConnection con = Connection();
		string command = "SELECT DISTINCT " +
				"Datum " +
			"FROM " +
				"Transaktionen " +
			"WHERE " +
			"(Datum >= '" + strfrom + "') AND (Datum <= '" + strto + "')";
		SqlCommand cmd = new SqlCommand(command, con);
		SqlDataAdapter da = new SqlDataAdapter(cmd);
		DataSet ds = new DataSet();
		da.Fill(ds);
		return ds;
	}

Das ist die Methode. Eigentlich relativ einfach.
Ich benutze Visual Studio Pro 2005 SP1 engl. und bei mir hat die Methode noch nie Ärger gemacht. Die Datenbank ist MS SQL, intern in VS angelegt als .mdf Datei
Auch als ich das zgh. Programm jemandem vorgeführt habe der die selbe Version vom VS, nur ohne SP1, gab es keine Fehler.

Bei meinen Teamkollegen die die deutsche Version nutzen wirft diese Methode beim Fill() allerdings eine SQL-Exception.
"Fehler beim Konvertieren von char nach datetime. Datetime außerhalb des zulässigen Bereichs". Ob es an der deutschen Version liegt weiß ich nicht...es ist aber das einzige was uns unterscheidet...
Ich hab bei denen heute sonst was probiert, ich verstehe einfach nicht woran der Fehler liegen soll.

Hat irgendjemand eine Idee was hier das Problem sein soll ? Ich kapier nicht warum es bei denen das Problem gibt und bei mir noch nie....

thx
belbono

R
494 Beiträge seit 2006
vor 17 Jahren

Der Fehler steht doch da, Fehler beim umwandeln von "strfrom" oder "strto" in ein Datetime klappt nicht.
Das Deutsche und Englische Datumsformat unterscheiden sich, deshalb vielleicht.

Unabhängig davon solltest du mit Parametern arbeiten und nicht den Query so zusammenfrickeln. http://de.wikipedia.org/wiki/SQL-Injection

T
512 Beiträge seit 2006
vor 17 Jahren

Bei unterschiedlichen Sprachen hat das Datum unter umständen auch unterschiedliches Format.

Bei uns ist es normal zuerst den Tag zu nennen, dann den Monat. In den USA sieht das wieder ganz anders aus.
1.7. würde in beiden Fällen verstanden, aber unterschiedlich.
15.7. würde in dem einen Fall einen Fehler verursachen, in dem anderen nicht.

Du hast 2 Möglichkeiten:

  1. Du konvertierst den Text explizit mit einer Funktion im SQL von einem ganz bestimmten Format. Da du dort explizit das Format angibst, wird immer das gleiche verwendet.

  2. Statt das Datum in die SQL Abfrage zu schreiben, benutzt du SqlParameter.

PS das ist nicht von der Version des Visual Studios abhängig, sondern von der Version des SQL Servers.

e.f.q.

Aus Falschem folgt Beliebiges

B
belbono Themenstarter:in
25 Beiträge seit 2006
vor 17 Jahren

Die Parameter sind vom Typ DateTime, weil das dann Schritt für Schritt ausprobiert wurde woran es liegen kann.

Die Konvertierung funktioniert! Mit dem Parameter "yyyy-MM-dd" gibt an, dass der String dann auch so aussieht. Damit sieht auch der parameter für die Sql-Anweisung so aus, dass in der Datenbank danach gesucht werden kann. Ok zwar sehen die datetime Werte in den Tabellen so ziemlich deutsch aus, aber mit diesem Format kann man der Datenbank nicht kommen - da funktioniert ohne die oben erwähnte Formatierung gar nichts.

Wie gesagt: Bei mir funktioniert die Methode ja tadellos!

Die Idee mit der Version des Sql-Servers hatten wir hier auch schon. Dummerweise wird an anderer Stelle eine ähnliche Anweisung genutzt in der nach einem bestimmten Datum in der Datenbank gesucht wird. Und dort funktionierts komischerweise!

.... mit DateTime parametern stell ich mir eine Sql-Injection schwer vor...

PS: ich habe das problem jetzt glaub ich lösen können, indem ich statt

(Datum >= '" + strfrom + "') AND (Datum <= '" + strto + "')"
"(Datum >= convert(datetime, '" + strfrom + "', 104)) AND (Datum <= convert(datetime, '" + strto + "', 104))";

stehen habe

502 Beiträge seit 2004
vor 17 Jahren

AUTSCH!
Man führt doch keine Typecasts ein um (noch dazu völlig unnötige) vorherige Casts wieder rückgängig zu machen. Das Mittel der Wahl sind definitiv SQL Parameter, weil 1.) keine Probleme mit anderen Datumsformaten auftreten, und 2.) das .net Framework Dir die ganze Arbeit abnimmt:

public static DataSet getTransaktDates(DateTime from, DateTime to)
    {        
        SqlConnection con = Connection();
        string command = "SELECT DISTINCT " +
                "Datum " +
            "FROM " +
                "Transaktionen " +
            "WHERE " +
            "(Datum >= @From) AND (Datum <= @To )";
        SqlCommand cmd = new SqlCommand(command, con);
		cmd.Parameters.AddWithValue("@From", from);
		cmd.Parameters.AddWithValue("@To", to);
        SqlDataAdapter da = new SqlDataAdapter(cmd);
        DataSet ds = new DataSet();
        da.Fill(ds);
        return ds;
    }

Wobei allerdings cmd.Parameters.AddWithValue erst ab .net 2.0 zur Verfügung steht, mit 1.x musst Du auf cmd.Parameters.Add zurückgreifen.

.... mit DateTime parametern stell ich mir eine Sql-Injection schwer vor...

Und was soll das nun heissen????

Bart Simpson

Praxis ist wenn alles funktioniert und keiner weiss warum.
Theorie ist wenn man alles weiss, aber nichts funktioniert.

Bei uns wird Theorie und Praxis vereint: Nichts funktioniert und keiner weiss warum...

B
belbono Themenstarter:in
25 Beiträge seit 2006
vor 17 Jahren

Das ist natürlich noch besser - nur lief es halt vorher auch, weshalb ich die Sorgen erst mal los war.

Dennoch danke für den Hinweis, so gefällt mir das ganze auch deutlich besser. Anders herum ist die Sache mit den Datumwerten u.U. ne lästige Sache...

S
53 Beiträge seit 2005
vor 17 Jahren

Parameter sind tausend mal besser, aber schau dir mal


SET DATEFORMAT dmy|ymd|...

an, vor eine SELECT-Anweisung gesetzt kannst du das DB Format ändern, was hier wahrscheinlich auch das Problem sein wird, die zweite DB wird eine andere Language gesetzt haben. Obwohl er die Vollständig ausgeschriebene ISO 8601 auch verstehen sollte, dies ist für Internationale Probleme gedacht.