PostgreSQL
La base de données la plus sophistiquée au monde.

Ouverture de session

Navigation

Contactez-nous

Administration du site :
"equipe chez postgresqlfr point org"

Contact presse :
"fr chez postgresql point org"

Contact association :
"bureau chez postgresqlfr point org"

Questions PostgreSQL :
 IRC :
  serveur irc.freenode.net
  canal #postgresqlfr

Recherche

Accéder aux archives

« Octobre 2008  
Lun Mar Mer Jeu Ven Sam Dim
  2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31  

Syndication

Flux XML

Sondage

Quelle est la version de PostgreSQL la plus répandue sur vos serveurs ?
8.3
10%
8.2
42%
8.1
40%
8.0
2%
7.4
6%
7.3 ou antérieure
0%
Nombre de votes: 48

Les DATES en SQL et plpgsql

Technique - Langages Procéduraux (PL) | Les DATES en SQL et plpgsql

Par dodo30 le 20/03/2007 - 16:21

Je cherche à calculer automatiquement la date de Règlement d'une facture avec un mode de règlement du type "60 jours Fin de mois le 10" !
J'ai donc essayé la requête suivante :

SELECT now(),DATE_PART('year', CURRENT_DATE) as Annee, DATE_PART('month', CURRENT_DATE) as MoisCour,
DATE_PART('month', CURRENT_DATE) + (60/30+1) as moisCalc,
TO_CHAR(DATE_PART('year', CURRENT_DATE)*100+DATE_PART('month', CURRENT_DATE) + (60/30+1),'99999999')||'01' as dt_text,
TO_DATE(TO_CHAR((DATE_PART('year', CURRENT_DATE)*100)+DATE_PART('month', CURRENT_DATE) + ((60/30)+1),'999999')||'01','YYYYMMDD') as dt_calc,
TO_DATE('20070601','YYYYMMDD')-1 as dt_CalMan,
TO_DATE(TO_NUMBER(TO_CHAR(CURRENT_DATE,'J'),'999999999999999')+70,'J') as dt_aut

où dt_text me calcule bien la bonne date, mais dt_calc est erroné !

J'ai essayé les autres ordre DATE, mais en plpgsql, il ne comprend pas la construction avec des variables pour interval (date_part(text, interval))

Options d'affichage des commentaires

Sélectionnez la méthode d'affichage des commentaires que vous préférez, puis cliquez sur "Sauvegarder les paramètres" pour activer vos changements.

Quelle est la question?

Jean-Paul Argudo/ = 20 Mars, 2007 - 20:06

Bonjour,

Vous êtes probablement un codeur habitué à une base de données propriétaires gérant mal les INTERVAL ? ;-)

Qu'essayez-vous de faire au juste? J'ai bien copié/collé votre requête dans une base de tests PostgreSQL, mais je n'arrive pas à discerner votre question...

Voilà le résultat (psql avec le mode \x):
-[ RECORD 1 ]---------------------------
now | 2007-03-20 18:52:32.20933+01
annee | 2007
moiscour | 3
moiscalc | 6
dt_text | 20070601
dt_calc | 2012-12-08
dt_calman | 2007-05-31
dt_aut | 2007-05-29

Que doit-on avoir pour dt_calc? Manifestement pas une date en 2012...

Ce que je constate de prime abord dans votre requête c'est que vous compliquez vraiment les choses... Si dt_text (1er juin 2007) est ce qu'on doit obtenir comme résultat, pourquoi ne pas faire simplement:

test=# select (extract (year from (current_date+interval '90 days'))||'-'||extract (month from (current_date+interval '90 days'))||'-10')::date;
-[ RECORD 1 ]----
date | 2007-06-10

J'espère n'être pas trop à côté de la plaque.. Si c'est le cas, merci de m'expliquer un peu plus en détail ce que vous avez et ce que vous voulez obtenir.

En tout cas, je vois d'un très mauvais œil vos divisions, multiplications et divisions :-)

--
Jean-Paul ARGUDO
http://dalibo.com | http://dalibo.org


Les dates en plpgsql

dodo30/ = 21 Mars, 2007 - 10:44

Merci pour la réponse,
Mais ce n'est pas un ordre SQL direct que je dois employer, mais du plpgsql.
Dans l'exemple, la valeur '90' est une variable plpgsql, ainsi que la valeur '10', hors même en créant une variable texte contenant les apostrophes de "interval", il n'arrive pas à interpréter la commande !
Par ailleurs, je ne comprends pas pourquoi la date dt_calc sort en 2012, alors que l'argument passé est bien en 2007.

Par ailleurs, mes divisions/multiplications permettent de déterminer un nombre de mois exact (tous à 30 jours), en non pas un nombre de jours correspondant pas obligatoirement à un nombre de mois suivant le calendrier.

En effet, le mode de règlement est défini en nombre de jours après la facture, un top Fin de mois, et un jour dans le mois suivant.
Si le nombre de jours est divisible par 30 ==> c'est donc un nombre de mois !


Réponses

Jean-Paul Argudo/ = 22 Mars, 2007 - 13:04

Mais ce n'est pas un ordre SQL direct que je dois employer, mais du plpgsql.

Ça ne fait aucune différence. Ce qui marche en SQL marche en plpgsql. Vous avez une erreur de syntaxe, tout bêtement, quelque part.

Dans l'exemple, la valeur '90' est une variable plpgsql, ainsi que la valeur '10', hors même en créant une variable texte contenant les apostrophes de "interval", il n'arrive pas à interpréter la commande !

CQFD :-)


Par ailleurs, je ne comprends pas pourquoi la date dt_calc sort en 2012, alors que l'argument passé est bien en 2007.

Parce qu'il manque deux "9" dans votre format de chaîne de caractères:

test=# select
TO_DATE(TO_CHAR((DATE_PART('year', CURRENT_DATE)*100)+DATE_PART('month',
CURRENT_DATE) + ((60/30)+1),'999999')||'01','YYYYMMDD') as dt_calc,
TO_DATE(TO_CHAR((DATE_PART('year', CURRENT_DATE)*100)+DATE_PART('month',
CURRENT_DATE) + ((60/30)+1),'99999999')||'01','YYYYMMDD') as dt_calc_juste;
dt_calc | dt_calc_juste
------------+---------------
2012-12-08 | 2007-03-11
(1 ligne)

Par ailleurs, mes divisions/multiplications permettent de déterminer un nombre de mois exact (tous à 30 jours)...

Ok. Si vous considerez que tous les mois font 30 jours, ça doit sûrement marcher.

Un paiement à 30 jours ne signifie en général pas qu'il s'agit d'un paiement dans 30 jours calendaires à partir de la date d'émission de la facture.

Maintenant, je ne suis pas au courant des pratiques de votre entreprise.

En espérant vous avoir apporté quelques lumières,

--
Jean-Paul ARGUDO
http://dalibo.com | http://dalibo.org


Les DATES en SQL et plpgsql

dodo30/ = 22 Mars, 2007 - 19:05

Merci,
mais votre solution avec 2 "9" en plus ne donne pas la bonne date non plus !
Vous trouvez le 11 Mars, alors qu'il faut trouver le 1er Juin !
J'ai par contre trouvé la solution :
Il faut enlever les espaces supplémentaires créés avec le TO_CHAR.
Dans ce cas, qu'il y ait 6 "9" ou plus, on trouve toujours la bonne date :
SELECT TO_DATE(TRIM(TO_CHAR((DATE_PART('year', CURRENT_DATE)*100)+DATE_PART('month',
CURRENT_DATE) + ((60/30)+1),'9999999999999')||'01'),'YYYYMMDD') as dt_calc_juste2

Il semblerait qu'il faille obligatoirement utiliser le TRIM avec le TO_CHAR !

Un mode de règlement peut être en jours calendaires ou en nombre de mois, dans ce dernier cas, le nombre de jours est donc un multiple de 30.

Je ne décide par contre pas des désirs de mode de règlement de mes clients, mais chacun a sa petite lubie ...

Merci encore


© PostgreSQLFr, tous droits réservés.
Site déclaré à la CNIL sous le numéro 1074678, conformément à la Loi en vigueur.