2017-10-26 1 views
0

Ich muss ein Tabellenfeld vergleichen, das ein Datum ist, das als Varchar im Format 'TT/MM/JJJJ' mit einem Datumswert gespeichert wird, aber der Vergleich schlägt fehl. Ich habe AusnahmeC# SQL Server-Vergleichsdatum mit Zeichenfolge

Konvertierung fehlgeschlagen beim Konvertieren von Datum und/oder Uhrzeit aus Zeichenkette. Ich habe versucht, die Umwandlung, das Datum zu vergleichen i nSTRING, wie diese

string dateFormat = date.ToString("dd/MM/yyyy"); 

und schreiben dann die Abfrage wie folgt aus:

string sql = "select * from TB_RICHIESTE where CONVERT(DATE, Date) <= CONVERT(DATE, '" + dateFormat + "')"; 

Aber ich habe diese excpetion. Jemand kann mir helfen? Danke

+6

* Nicht *. Verwenden Sie den richtigen Typ für das Feld * und * den Parameter. Und konstruieren Sie keine SQL-Anweisungen, indem Sie Strings verketten. Verwenden Sie parametrisierte Abfragen –

+0

Wenn die * Tabelle * ein Datum in der Form "TT/MM/JJJJ" hat, gibt es einen sehr ernsten Fehler. Der Feldtyp sollte auf "Datum" korrigiert werden. Sie können nicht nach einem solchen Feld sortieren oder nach Datumsbereichen suchen, zB nach einem bestimmten Datum. –

Antwort

5

Zuerst, sollten Sie Daten nicht als Zeichenfolgen speichern.
Wie Panagiotis Kanavos in seinem Kommentar schrieb - das ist ein ernsthafter Fehler. Sie können nicht nach einer solchen Spalte sortieren, Sie können nicht nach Datumsbereichen suchen, und am wichtigsten - Sie können nicht kontrollieren, ob jemand einen ungültigen Wert eingibt - nichts hält jemanden davon ab, "Alfredo" in diese Spalte einzugeben.
Weitere Informationen finden Sie in Aaron Bertrands Bad habits to kick : choosing the wrong data type.

Zweitens sollten Sie keine Daten von .Net zu Sql-Server als Zeichenfolgen übergeben. Sie sollten Instanzen von DateTime als Parameter übergeben. Das .Net DateTimemaps directly zu SQL Server Date.

Wenn Sie den Datentyp der Spalte nicht ändern können, können Sie ihn zumindest mit dem richtigen convert style (in Ihrem Fall 103) in ein Datum konvertieren.

Hier ist ein besserer Weg, es zu tun:

var sql = "select * from TB_RICHIESTE where CONVERT(DATE, [Date], 103) <= @Date"; 

Dann fügen Sie den @Date Parameter an die SqlCommand:

com.Parameters.Add("@Date", SqlDbType.Date).Value = date.Date; 
+0

Etwas besser: '... .Value = date.Date;'. Dann funktioniert es auch, wenn der Typ in der Datenbank 'DateTime' ist (oder sein wird). –

+0

@TimSchmelter Ich überführe bereits den Datentyp der Spalte in 'Date' und der Datentyp des Parameters ist auch' Date'. Ich sehe nicht, dass das Senden von "date.Date" anstelle von "date" etwas verändern würde. –

+0

Perfekte Lösung. Danke –

0

Verwendung Parameter Datumswerte beziehen post @Zohar Peled zu übergeben. Dies ist die richtige Methode zur Verarbeitung von Datumswerten. ODER Sie können den Datumswert im ISO-Format übergeben, siehe unten stehenden Code.

string dateFormat = date.ToString("yyyy/MM/dd"); 


string sql = "select * from TB_RICHIESTE where CONVERT(DATE, Date) <= CONVERT(DATE, '" + dateFormat + "')"; 
+0

Erstens ist dies kein ISO-Format. Wenn Sie Zeichenfolgenliterale für Daten übergeben müssen, verwenden Sie 'yyyy-mm-dd' oder besser noch' yyyymmdd'. Zweitens ist das Verketten von Strings in SQL-Anweisungen riskant, da es eine offene Tür für SQL-Injection-Angriffe ist. Ist vielleicht nicht der Fall hier, aber es ist immer besser, Parameter zu verwenden, anstatt Strings zu verketten. –

+0

Wenn das echte ISO oder das nicht getrennte Format verwendet wird, gibt es keinen Grund den * Parameter * zu konvertieren. Das Konvertieren des * -Feldes * ist eine schlechte Idee, die verhindert, dass die Datenbank Indizes verwendet und zu einem vollständigen Tabellenscan führt –