2013-04-16 8 views
7

sto modificando un'interrogazione, qui è il mio script:In che modo SQL Server confronta una data con una stringa letterale?

select 
CASE When EndDate='1/1/1900' 
THEN NULL 
ELSE EndDate END,* 
from Members 

Questo script confronta semplicemente la data, se si tratta di '1/1/1900' poi torna null altrimenti restituisce la data.

posso vedere nel mio data base di dati viene memorizzato nel seguente formato:

1900-01-01 00:00:00.000 

domanda è come SQL Server è data così la corrispondenza quando il mio modello è differente da quella memorizzata. Anche nel formato della data non sto passando l'elemento del tempo.

+0

sguardo nel 'funzione DATEPART'. Vedi http://msdn.microsoft.com/en-us/library/aa258265(v=sql.80).aspx –

+2

@ PM77-1 hai letto la domanda? –

+0

Beh ... l'ho fatto. Ho fatto un errore. Significa "CONVERT". –

risposta

17

SQL Server converte la stringa letterale che si sta passando ('1/1/1900') in un valore datetime a causa di data type precedence (since datetime has higher precedence than string types). Se passi una data non valida come stringa, ad es. '2/31/1900', si verificherà un errore di conversione (Msg 242) perché SQL Server non sa cosa significhi il 31 febbraio. Non sta cercando di abbinare una stringa che assomiglia a ciò che stai passando, si converte sia nella sua rappresentazione interna per le date (più su questo nel mio commento).

Quando si tratta di date specifico, smettere di pensare a un formatotranne che quando si passa letterali stringa, m/d/y (o è che d/m/y?) È un formato terribile da usare. Molto più sicuro da utilizzare:

YYYYMMDD 

Vostri criteri dovrebbe leggere:

SELECT CASE When EndDate = '19000101' 
THEN NULL ELSE EndDate END, ...other columns... 
FROM dbo.Members; 

In questo modo, quando si passa una data come 8 settembre, ma non è male interpretato da SQL Server, gli altri lettori, ecc è 09/08/2013 8 settembre o 9 agosto? Dipende da quale parte del mondo sei, giusto? Nel tuo caso va bene, perché il giorno e il mese sono gli stessi, ma non sarà sempre così. Si prega di consultare il seguente articolo:

http://sqlblog.com/blogs/aaron_bertrand/archive/2009/10/16/bad-habits-to-kick-mishandling-date-range-queries.aspx

(. Favore, per favore, si prega di leggere quel link nella sua interezza)

Infine, se si utilizza DATETIME/SMALLDATETIME e siete alla ricerca di valori da un giorno specifico, non dovresti usare l'uguaglianza, ma piuttosto una query di intervallo. Ad esempio, per trovare tutte le righe in cui EndDate cade il 15 aprile 2013, a prescindere dal tempo, si potrebbe dire: (. Read this link to understand why you don't want to use BETWEEN here)

WHERE EndDate >= '20130415' 
    AND EndDate < '20130416' 

Se siete su SQL Server 2008 o meglio, è ancora possibile ottenere sargibilità su questa colonna con CONVERT, ma questa è un'eccezione rara, in genere non si desidera utilizzare una funzione su una colonna.

WHERE CONVERT(DATE, EndDate) = '20130415' 

Un paio di altre osservazioni - non direttamente correlate alla tua domanda, ma periferici osservazioni circa il vostro codice:

  1. Always use the schema prefix
  2. Never use SELECT * in production
+0

grazie per aver partecipato alla mia domanda. Cosa intendi per "smettere di pensare a un formato"? Vuoi dire per una data memorizzata per SQL Server è lo stesso se ho inserito la data per l'abbinamento 1/2/1900 o 2/1/1900 o 1900/2/1 e anche 1900/1/2? Potete per favore chiarirlo. – user576510

+4

Voglio dire che SQL Server non * memorizza * la tua data nel formato leggibile dall'uomo che pensi che faccia. Memorizza internamente la data come due interi che rappresentano rispettivamente il giorno e l'ora. Quando si passa una stringa a SQL Server, l'interpretazione dipende dalle impostazioni internazionali, dalle impostazioni della lingua, dalle impostazioni di dataformat, ecc. Quindi se si memorizza il 2 gennaio nel database, utilizzando '1/2/1900' potrebbe trovare la riga, potrebbe non . Usando '2/1/1900' potrebbe trovare la tua riga, potrebbe non farlo. Questi dipendono da varie impostazioni (per maggiori informazioni, leggi il link). Se usi '19000102' non ci sarà mai alcuna confusione ... –

+0

1. Nel 19000102, 01 è il mese e 02 è la data giusta? 2. Continuerà a prendere in considerazione la data dell'ora o non quella della corrispondenza? 3. Intendi 19000102 è sempre sicuro fare qualsiasi cosa siano le impostazioni regionali sul server? Grazie mille per aver chiarito tutti questi – user576510

Problemi correlati