2016-05-13 4 views
0

Ich möchte dynamisch nach einem Datum in meiner Datenbank nach meinem $ Dateneingabe suchen.DATETIME vs LIKE zu einer dynamischen Suche SQL

Datumsangaben werden als Datum-Uhrzeit gespeichert und werden normalerweise als "2016-05-11" angezeigt.

mit einer MySQL-DB meiner Klausel war:

Select * From Table WHERE (Table.date LIKE '$data%') 

Also, wenn der Benutzer „20“ tritt die Ergebnisse alle Daten, die mit 20 beginnen Wenn der Benutzer eingibt „2016-05“ die Ergebnisse Seien Sie alle Termine, die mit 2016-05 beginnen, so dass meine Suche perfekt funktioniert.

Bei der Bereitstellung über einen SQL Server 2008. Ich realisierte 2 Dinge.

1) Wenn ich die Funktion LIKE als solche

verwenden
Select * From Table WHERE (Table.date LIKE '%$data$%') 

Die Funktion wird für einen Wert von „2016“ arbeiten, würde aber 0 Ergebnisse zurück, wenn ein Wert von „2016-“ eingegeben wird.

2) Wenn ich die Funktion DATETIME- als solche

Select * From Table WHERE (DATEPART(year, Table.date) LIKE(OR)= '$data') 

Die Funktion wird korrekten Werte zurück, wenn $ data = 2016, wird aber gleich Null Werte zurückgeben, wenn die ‚201‘ $ data = zum Beispiel, daher mach es nicht dynamisch.

Was mache ich falsch?

+0

Die Problem ist bei der Eingabevalidierung. Wenn ein Benutzer "20" eingeben kann, kann er auch "fred" oder "2016-02-30" eingeben. –

+0

Ich benutze Ajax Anrufe also wenn sie Fred eingeben. Sie werden keine Ergebnisse bekommen. Das ist kein Problem? Bin ich nicht richtig? – MakDo

Antwort

0

Implizite Konvertierung ist einfach schlecht, schlecht, schlecht - in SQL oder den meisten anderen Programmiersprachen.

LIKE wirkt auf Strings. Wenn Sie möchten, dass es mit Strings arbeitet, dann stellen Sie sicher, dass die Parameter explizit Strings sind. Dies gilt für MySQL und SQL Server.

Wenn Sie LIKE auf das Jahr verwenden möchten, verwenden Sie dann DATENAME() statt DATEPART():

WHERE DATENAME(year, Table.date) LIKE '$data' 

Aber ich möchte Sie ermutigen, über Termine mit Datum-basierte Konstrukte, wie Datumsbereiche zu denken.

+0

Aber, meine Eingabe ist eine Zeichenfolge! Ich sage dem Benutzer explizit, dass er eine YYYY-MM-DD-Zeichenfolge eingeben soll, und meine Suche wird entsprechend ausgeführt. Das ist also kein Problem!? – MakDo

+1

Fast jede Anwendung, die nach Datum sucht, verwendet Datumsbereiche. Selbst wenn Sie eine bessere Möglichkeit gefunden haben, nach Daten zu suchen, an die noch niemand gedacht hat (zweifelhaft), ist es das, was die Leute erwarten. Wenn ich auf eine Buchungswebsite für Fluggesellschaften gehe und nach Datum suchen möchte, erwarte ich nicht, "2016-06-" einzugeben, um im Juni nach Flügen zu suchen. Wie würde man nach Daten zwischen 2016-05-18 und 2016-05-21 suchen? –

+1

@ MakDo. . . Dann * explizit * den Datumswert in eine Zeichenkette konvertieren, mit 'date_format()' oder 'convert()'. Alle diese Methoden schließen übrigens die Verwendung von Indizes aus - implizite Konvertierungs- und Funktionsaufrufe stören im Allgemeinen die Indexnutzung. –

0

Ich habe gerade meinen dummen Fehler erkannt. Ich musste meiner LIKE-Klausel einen Platzhalter hinzufügen, indem ich DATEPART als solches verwende.

Wählen Sie * aus der Tabelle WHERE (DATEPART (Jahr, Table.date) LIKE = '$ data%').

Funktioniert perfekt.

Aber ich würde gerne andere Vorschläge zu vereinfachen $ Daten in YYYY, MM, DD teilen und dann jedes Element testen.

0

Ich würde versuchen, Table.date frei von Manipulation zu halten, so Indizes verwendet werden.

Stattdessen können Sie einen CASE Ausdruck verwenden, um die Suchparameter auf einen Datumsbereich zu konvertieren, indem die fehlenden Teile ergänzt:

Untere Grenze:

CASE LENGTH($data) 
WHEN 8 THEN $data + '01' 
WHEN 7 THEN $data + '-01' 
WHEN 5 THEN $data + '01-01' 
WHEN 4 THEN $data + '-01-01' 
ELSE $data 
END 

Obere Grenze:

CASE LENGTH($data) 
WHEN 8 THEN DATEADD(MONTH,$data + '01',1) 
WHEN 7 THEN DATEADD(MONTH,$data + '-01',1) 
WHEN 5 THEN DATEADD(YEAR,$data + '01-01') 
WHEN 4 THEN DATEADD(YEAR,$data + '-01-01') 
ELSE DATEADD(DAY,$data,1) 
END