2009-06-09 7 views
4

Après commande SQLintervalle de format avec to_char

select TO_CHAR(NVL(arg1 - arg2, TO_DSINTERVAL('0 00:00:00'))) from table1 

produit un résultat du format: 000000000 00: 03: 01,954000.

Est-il possible d'entrer un format spécial dans la fonction to_char pour obtenir un résultat de format: +00 00: 00: 00.000?

Répondre

2

Je me rends compte qu'il est pas intelligent du tout, ni la chaîne de format spécial que vous cherchez, mais cette réponse fonctionne, étant donné que la sortie est longueur fixe:

SELECT SUBSTR(TO_CHAR(NVL(arg1 - arg2, TO_DSINTERVAL('0 00:00:00'))), 1, 1) 
     || SUBSTR(TO_CHAR(NVL(arg1 - arg2, TO_DSINTERVAL('0 00:00:00'))), 9, 2) 
     || ' ' 
     || SUBSTR(TO_CHAR(NVL(arg1 - arg2, TO_DSINTERVAL('0 00:00:00'))), 12, 12) 
    FROM table1; 

Il a également juste tronque les secondes fractionnaires au lieu d'arrondir, mais je suppose de votre exemple, ils sont tous juste des zéros de toute façon.

Ceci est encore plus d'embarras, mais je ne pouvais pas résister:

SELECT SUBSTR(REPLACE(TO_CHAR(NVL(arg1 - arg2, TO_DSINTERVAL('0 00:00:00'))) 
        , '0000000', '') 
      , 1, 16) 
    FROM table1; 
+0

votre deuxième proposition fonctionne bien! aussi avec HQL. Merci beaucoup pour votre aide! –

17

vous pourriez lancer le résultat si vous voulez moins de précision:

SQL> SELECT TO_DSINTERVAL('10 10:00:00') t_interval FROM dual; 

T_INTERVAL 
----------------------------------------------------------- 
+000000010 10:00:00.000000000 

SQL> SELECT CAST(TO_DSINTERVAL('10 10:00:00') 
    2     AS INTERVAL DAY(2) TO SECOND(3)) t_interval 
    3 FROM dual; 

T_INTERVAL 
----------------------------------------------------------- 
+10 10:00:00.000 

Modifier commentaire suivant OP:

De La Oracle Documentation (11gr1):

types de données Intervalle n'ont pas des modèles de format. Par conséquent, pour ajuster leur présentation, vous devez combiner des fonctions de caractères telles que EXTRACT et concaténer les composants.

Il semble que vous devrez utiliser manuellement EXTRACT pour obtenir la sortie désirée:

SQL> SELECT to_char(extract(DAY FROM t_interval), 'fmS99999') || ' ' || 
    2   to_char(extract(HOUR FROM t_interval), 'fm00') || ':' || 
    3   to_char(extract(MINUTE FROM t_interval), 'fm00') || ':' || 
    4   to_char(extract(SECOND FROM t_interval), 'fm00.000') 
    5 FROM (SELECT TO_DSINTERVAL('10 01:02:55.895') t_interval FROM dual) 
    6 ; 

TO_CHAR(EXTRACT(DAYFROMT_INTER 
------------------------------ 
+10 01:02:55.895 


Ce n'est pas très élégant, mais il semble que ce soit la seule façon de traiter avec une précision de microsecondes.

+0

Votre proposition semble être très proche de la solution J'ai besoin. Sur SQL, la commande fonctionne bien, mais j'ai besoin de l'interroger via HQL en hibernation. En utilisant cette commande hibernate jette exception suivante: org.hibernate.hql.ast.QuerySyntaxException: attendez FERMER, trouvé 'DAY' –

+0

J'ai édité ma réponse: Je n'ai jamais travaillé avec HQL mais peut-être qu'il ne connaît pas le type de données d'intervalle , vous devrez donc le convertir manuellement. –

+0

Malheureusement, Hibernate n'en est pas conscient. –

6

to_char() semble avoir le format fixe :(si regexp_substr peut être une option, par exemple:

SELECT regexp_substr (TO_DSINTERVAL ('10 10:00:00'), '\d{2} \d{2}:\d{2}:\d{2}\.\d{3}') t_interval FROM dual 
1

Léger cas de nécromancie de threads, cependant je suis tombé sur cette question en cherchant comment formater un intervalle, donc j'ai pensé qu'il valait la peine d'ajouter ce commentaire

Depuis le Oracle documentation, l'ajout d'un horodatage à un résultat d'intervalle dans un horodatage, donc en ajoutant un horodatage constant avec zéro éléments de temps, vous pouvez alors utiliser la norme to_char format elements pour datetime ...

SELECT TO_CHAR(TIMESTAMP'1969-12-31 00:00:00' + TO_DSINTERVAL('0 00:03:01.954321'), 
    'HH24:MI:SS.FF3') FROM dual; 

Cependant, il y a un émettre si vos intervalles pourraient être supérieurs à un jour. Il n'y a pas d'élément de format pour les jours qui donneront 0. "DDD" est le jour de l'année, donc 365 dans l'exemple ci-dessus, ou 1 ou plus si l'intervalle était supérieur à un jour. C'est bien aussi longtemps que vos intervalles sont moins de 24 heures.

Devrait ajouter ceci est sur 11g donc peut ne pas être applicable à l'OP.

0

Vous pouvez supprimer la dernière partie (ou toute partie) avec l'expression régulière Oracle REGEXP_REPLACE fait exactement cela.

select regexp_replace (TO_CHAR (NVL (arg1 - arg2, TO_DSINTERVAL ('0 00:00:00'))), '.. *') de table1

+1

OU UTILISATION CAST: TO_CHAR (CAST ( COMME INTERVALLE JOUR (2) à la SECONDE (0))) – Leon

Questions connexes