web-dev-qa-db-fra.com

Convertir un horodatage Unix en DATETIME dans une vue

J'ai une table qui stocke un horodatage Unix. Pour l'interroger en tant que date, j'essaie de convertir cet horodatage en un type datetime dans une vue. Malheureusement, je peux seulement sembler sortir la partie DATE.

Ce lien décrit comment faire la conversion, mais nécessite de changer le nls_date_format pour inclure la portion de temps. La valeur par défaut ne montre actuellement que la partie date. J'ai besoin de la date et de l'heure.

Malheureusement, cette solution ne fonctionne qu'au niveau d'une session. En tant que développeur, je préfère ne pas avoir à courir chez notre fournisseur de services gérés pour leur demander de modifier la valeur au niveau de la base de données - d'autant plus que cela peut avoir un impact sur d'autres applications.

Existe-t-il un moyen de convertir l'horodatage, en sql, en datetime sans modifier le système?

7
Josh Smeaton

le résultat de l'expression

to_date('1970-01-01','YYYY-MM-DD') + numtodsinterval(1244108886,'SECOND')

est une valeur du type de données Oracle DATE. Ce type contient la date et l'heure. Si vous souhaitez afficher cette valeur pour un utilisateur, vous devez la convertir en chaîne. Cette conversion peut être effectuée par une application ou vous pouvez laisser Oracle la convertir en un type de chaîne comme cela est fait dans cet exemple. Cette conversion automatique en Oracle stringtype VARCHAR2 est contrôlée par nls_date_format et certains paramètres du serveur. Si vous souhaitez que votre vue renvoie une valeur VARCHAR2 avec la date calculée au format 'AAAA-MM-JJ HH24: MI: SS' et non une valeur DATE, vous pouvez le faire en utilisant une fonction de conversion: expression

to_char(to_date('1970-01-01','YYYY-MM-DD') + numtodsinterval(1244108886,'SECOND'),'YYYY-MM-DD HH24:MI:SS')

Mais dans ce cas, la valeur de retour de la vue est un VARCHAR2 et non une valeur DATE.

12
miracle173

La meilleure pratique consiste à éviter les appels de fonction non SQL dans les requêtes SQL car la fonction peut ne pas être universellement disponible - dans mon système, il n'y a pas de fonction numtodsinterval - également en raison de la surcharge supplémentaire pour basculer le contexte de SQL vers PL/SQL, puis retour à SQL pour chaque ligne retournée ou testée si la fonction est appelée dans la clause where.

Voici une solution SQL uniquement.

TO_DATE('1970-01-01','YYYY-MM-DD') + unix_timestamp / 86400

Notez que le résultat est une valeur Oracle DATE qui contient également le TIME. S'il ne semble pas avoir TIME lorsque vous exécutez la requête, le problème se trouve dans votre NLS_DATE_FORMAT ou dans la mise en œuvre par votre interface utilisateur de la conversion des dates en chaînes. Assurez-vous de faire TO_CHAR vous-même avec la portion de temps dans la chaîne de format afin de voir la valeur entière. par exemple. TO_CHAR (a_date, 'aaaa-mm-jj hh24: mi: ss')

5
user21435

J'ai utilisé un autre nombre pour calculer cette valeur.

select (TO_DATE('1970-01-01','YYYY-MM-DD') + unix_timestamp / 86400000) from dbname;

Ce script fonctionne bien pour moi.

1
bpedroso

Si l'unix_timestamp doit être comparé à une certaine plage de dates dans la clause WHERE, il est préférable de convertir les dates en unix_timestamps au lieu de convertir toutes les valeurs unix_timestamp en dates.

Par exemple, les éléments suivants peuvent rechercher les lignes avec UNIX_TIMESTAMP entre la date de début et la date de fin spécifiées.

WHERE unix_timestamp BETWEEN
       (:start_date - TO_DATE('1970-01-01','YYYY-MM-DD')) * 86400
       AND 
       (:end_date - TO_DATE('1970-01-01','YYYY-MM-DD')) * 86400

Cela permettra également d'utiliser un index sur UNIX_TIMESTAMP, s'il y en a un.

0
user21435