Access 2003 SQL Switch interrompe i tipi di dati?
-
20-09-2019 - |
Domanda
Sto eseguendo Access 2003.Sto utilizzando Switch per selezionare i campi data in base a un criterio booleano:
Switch(<criterion>, Date1, 1, Date2)
cioè, se "criterio" è vero, restituisce Data1, altrimenti restituisce Data2.
Data1 e Data2 sono colonne di tipo Data/Ora in una tabella.
Il problema è che Switch li restituisce come testo, non come data/ora!
C'è un modo per forzarli ad essere aggiornati?ho provato
Switch(<criterion>, #Date1#, 1, #Date2#)
E
Switch(<criterion>, Val(Date1), 1, Val(Date2))
Entrambi falliscono con un messaggio di errore o un altro.
Qualche idea?
Soluzione
Penso che la funzione Immediate If [IIf()] sia una corrispondenza migliore per ciò che stai cercando di fare:
IIf(<criterion>, Date1, Date2)
Ma la funzione Switch() non dovrebbe interrompere i tipi di dati e non è incompatibile con i tipi di dati di data/ora.Considera questa funzione:
Public Function trySwitch(ByVal pWhichDay As String) As Variant
Dim varOut As Variant
varOut = Switch(pWhichDay = "yesterday", Date - 1, _
pWhichDay = "today", Date, _
pWhichDay = "tomorrow", Date + 1)
trySwitch = varOut
End Function
provaSwitch("oggi") ritorna 10/6/2009 E NomeTipo(provaSwitch("oggi")) ritorna Data
Altri suggerimenti
C'è qualcosa di strano con il vostro esempio.
sensore riconosce coppie di espressione, e se il primo valore True, viene restituito il suo valore associato, altrimenti si passa alla seconda, e valuta tale argomento.
Sembra che tu stia trattando 1 come True, che è perché non è Fales, ma si sarebbe meglio con:
Switch(<criterion>, Date1, True, Date2)
Ma questa è solo una replica della funzionalità della funzione immediata Se, IIf (), e IIf () prende un numero di argomenti.
Ma ha lo stesso problema, in quanto restituisce una variante. Ma si dovrebbe essere in grado di costringere che a un tipo di dati che può essere formattato come una data.
Ma se quella variante verrà implicitamente costretti o dovrete farlo in modo esplicito, dipende da dove lo si usa. In un risultato della query, è possibile ordinare l'output di IIf ([criterio], Data1, Data2) come una data, perché la colonna viene costretto al tipo di data.
Se avete a che fare la costrizione in modo esplicito, CDate () è la funzione da utilizzare - che ci avvolgono la funzione esterna che produce output Variante con la funzione CDate () in modo da essere certi che l'uscita variante è esplicitamente costretto al tipo di data:
CDate(IIf(<criterion>, Date1, Date2))
Ma potrei benissimo essere manca qualcosa di importante qui, come mi sembra di essere fuori su una pista completamente diversa ...
Puoi pubblicare un po 'di codice e dati per riprodurre il problema, per favore? Poiché questo è SWITCH()
nel codice SQL allora penso SQL DDL (CREATE TABLE
, ecc) e DML (INSERT INTO
per aggiungere dati) sarebbe più appropriata:)
[punto Picky: accesso database SQL non ha un tipo di dati 'booleano'. Ha un tipo di dati YESNO
che può essere il valore NULL
; logica a tre-valore non è booleano.]
Ecco alcuni SQL DML ( ANSI-92 modalità query sintassi ) per dimostrare come funziona come previsto per me:
SELECT TYPENAME
(
SWITCH
(
NULL, #2009-01-01 00:00:00#,
FALSE, #2009-06-15 12:00:00#,
TRUE, #2009-12-31 23:59:59#
)
);
Modificare uno dei valori 'criterio' e il valore viene sempre restituito come 'Data' vale a dire di tipo DATETIME
.
UPDATE:
Questa funzione
TYPENAME
è un grande strumento ... L'accesso sembra interpretare la intero "colonna" del gruppo di risultati diversamente
In effetti. Poiché una colonna può essere solo tipo di dati i risultati del TYPENAME()
alla fila possono essere fuorvianti. valori di riga di tipi misti devono essere 'promossi' a un tipo di dati più elevato. Come al solito con il motore di database di Access, il processo è del tutto opaco e la documentazione sul tema del tutto assente, in modo da avere solo a succhiare e vedere per esempio
SELECT #2009-01-01 00:00:00# AS row_value,
TYPENAME(#2009-01-01 00:00:00#) AS row_type
FROM Customers
UNION ALL
SELECT 0.5,
TYPENAME(0.5) AS row_type
FROM Customers
restituisce 'Data' e 'decimale', rispettivamente, ma quale sarà la colonna sarà? A quanto pare, la risposta è:
SELECT DT1.row_value, TYPENAME(DT1.row_value) AS column_type
FROM (
SELECT DISTINCT #2009-01-01 00:00:00# AS row_value
FROM Customers
UNION ALL
SELECT DISTINCT 0.5
FROM Customers
) AS DT1;
'String'?!
... che ovviamente non è nemmeno un database di Access tipo di dati del motore di SQL. Così TYPENAME()
, fastidiosamente, utilizza il nome del 'best fit' tipo VBA. Ad esempio:
SELECT TYPENAME(CBOOL(0));
ritorna 'booleana', anche se, come discusso in precedenza, non v'è alcun tipo di dati booleano in Access SQL motore di database. E
SELECT TYPENAME(my_binary_col)
restituisce 'String'. Nota la stessa limitazione mappatura VBA applica alle funzioni CAST
(ancora un'altra fastidio) esempio non v'è alcuna funzione 'cast di BINARY
' e la funzione di CDEC()
rimane rotto dal Jet 4.0: (