Istruzione SQL con datetimepicker
-
05-07-2019 - |
Domanda
Speriamo che questo sia semplice. Quando utilizzo un selettore di data e ora in un modulo di Windows, voglio eseguire un'istruzione SQL, in questo modo:
string sql = "SELECT * FROM Jobs WHERE JobDate = '" + dtpJobDate.Text + "'";
Sfortunatamente, questo in realtà non fornisce alcun risultato perché il campo JobDate è archiviato come valore DateTime. Mi piacerebbe essere in grado di cercare tutti i record in questa data, qualunque sia il tempo memorizzato, qualche aiuto?
Nuova query:
SqlDataAdapter da2 = new SqlDataAdapter();
SqlCommand cmd = new SqlCommand();
cmd.CommandText = "SELECT * FROM Jobs WHERE JobDate >= @p_StartDate AND JobDate < @p_EndDate";
cmd.Parameters.Add ("@p_StartDate", SqlDbType.DateTime).Value = dtpJobDate.Value.Date;
cmd.Parameters.Add ("@p_EndDate", SqlDbType.DateTime).Value = dtpJobDate.Value.Date.AddDays(1);
cmd.Connection = conn;
da2.SelectCommand = cmd;
da2.Fill(dt);
dgvJobDiary.DataSource = dt;
Grazie enormi per tutto l'aiuto!
Soluzione
Solo una risposta: usa query parametrizzate .
Questo per diversi motivi:
- sicurezza (nessun rischio di SQL Iniezione
- non sono più quei problemi per i quali stai aprendo un argomento
- prestazioni.
Quindi, scrivi la tua dichiarazione in questo modo:
SqlCommand cmd = new SqlCommand();
cmd.CommandText = "SELECT * FROM Jobs WHERE JobDate = @p_Date"
cmd.Parameters.Add ("@p_Date", SqlDbType.DateTime).Value = dtpJobDate.Value;
Se vuoi ignorare il tempo, penso che la scommessa migliore sia fare una ricerca di intervallo, se il tempo è memorizzato nel DB, cioè. Qualcosa del genere (solo la query SQL):
SELECT * FROM Jobs WHERE JobDate >= @p_StartDate AND JobDate < @p_EndDate
StartDate sarebbe quindi dtpJobDate.Value.Date
e EndDate sarà dtpJobDate.Value.Date.AddDays(1)
Se l'ora non è memorizzata nel DB, è possibile farlo:
SELECT * FROM Jobs WHERE JobDate = @p_Date
dove l'argomento di ricerca dovrebbe essere dtpJobDate.Value.Date
Altri suggerimenti
Prova dtpJobDate.Value.
Oltre alle cose di SQL injection in altre risposte, puoi usare qualcosa del genere:
dtpJobDate.Value.ToString("yyyyMMdd HH:mm:ss");
Ma probabilmente non troverai nulla con la corrispondenza esatta del tempo, quindi puoi cambiare la tua query per qualcosa come
string sql = "SELECT * FROM Jobs WHERE JobDate BETWEEN '" + dtpJobDateStart.Value.ToString("yyyyMMdd HH:mm:ss") + "' AND '" + + dtpJobDateEnd.Value.ToString("yyyyMMdd HH:mm:ss") + " + "'";
Prima di tutto, hai lasciato una porta aperta per l'iniezione SQL nel tuo esempio.
A parte questo, per rispondere alla tua domanda, dovrai eliminare i tempi dalla colonna JobDate per completare la partita. Prova qualcosa del genere (codice SQL Injection lasciato nell'esempio per il confronto) ...
string sql = "SELECT * FROM Jobs WHERE CAST(CONVERT(CHAR(8), JobDate, 112) AS DATETIME) = '" + dtpJobDate.Text + "'";
Se dovessi parametrizzare la tua query, potresti farlo in questo modo ...
using (var conn = new SqlConnection(myConnectionString))
using (var cmd = new SqlCommand("SELECT * FROM Jobs WHERE JobDate = @JobDate", conn))
{
cmd.Parameters.Add(new SqlParameter("@JobDate", dtpJobDate.Value));
conn.Open();
using (var reader = cmd.ExecuteReader())
{
while (reader.Read())
{
// your code here to deal with the records...
}
}
}