Nous utilisons des cookies pour vous garantir la meilleure expérience sur notre site. Si vous continuez à utiliser ce dernier, nous considèrerons que vous acceptez l'utilisation des cookies. J'ai compris ! ou En savoir plus !.
banniere

Le portail francophone de la géomatique


Toujours pas inscrit ? Mot de passe oublié ?
Nom d'utilisateur    Mot de passe              Toujours pas inscrit ?   Mot de passe oublié ?

#1 Mon 13 September 2010 01:19

map
Juste Inscrit !
Lieu: cournonsec (34)
Date d'inscription: 24 Feb 2006
Messages: 8

[postGis] création en "numéro Auto" d'une chaine type YYYYMMDDH24MISSM

Bonsoir,

Désolé, je sèche... peut-être n'ai-je pas cherché au bon endroit... mais là j'appelle a l'aide!

Situation :
- Une table "geo", simple, sous PostGre / PostGis (un seul champ texte de longueur 20 caract., objets type "point")
- Données interfacées avec QGis (1.5)

Besoin :
- Générer, à la création de l'objet point, une chaine de caractères dans le (seul) champ text qui soit basé sur LOCALTIMESTAMP (3) et au format YYYYMMDDH24MISSMS (donc 17 caract dont 8 pour date + 6 pour l'heure min seconde + 3 pour miliseconde)

Pistes explorées :
- PostGre : les "numéro auto"... je laisse tomber, les incréments ne gèrent pas les valeurs de date
- PostGre : les "valeur par défaut"... j'ai essayé... mais lors de la création d'un objet sous QGis, un formulaire s'ouvre et me propose... la chaine SQL ou la fonction apellée (now())... non interprétée (un "now()", comme ça, texto...grrr)
- PostGre : les "valeur par défaut"... j'ai même essayé avec une fonction... pas moyen!

... du coup ça me fait explorer la piste "formulaire", j'installe QT... mais bon, là je bloque sur un qmake.exe manquant... et je sort du sujet du forum!

Deux questions :
- Par quel bout dois-je prendre l'affaire? Par PostGreSql ou par l'interface QuantumGis (donc QT)?
- Please help me...??? (style solution toute faite, ce s'rait vraiment parfais, mais sinon, rien qu'une piste je prends aussi ;+)


En vous remerciant ;+)

Patrick.

Hors ligne

 

#2 Mon 13 September 2010 10:20

saispasfau
Participant actif
Date d'inscription: 28 Nov 2006
Messages: 62

Re: [postGis] création en "numéro Auto" d'une chaine type YYYYMMDDH24MISSM

Bonjour.

Si j'ai bien saisi le besoin, le champ text doit être rempli avec la valeur de LOCALTIMESTAMP à l'insertion dans la table geo. Pourquoi ne pas utiliser tout simplement un trigger ?

Code:

CREATE OR REPLACE FUNCTION BIU_GEO_LOCALTIMESTAMP()
  RETURNS "trigger" AS 
$BODY$ 
begin
    NEW.text := to_char(LOCALTIMESTAMP,'YYYYMMDDH24MISSMS');
    return NEW ;
end;$BODY$
  LANGUAGE 'plpgsql' VOLATILE
  
ALTER FUNCTION BIU_GEO_LOCALTIMESTAMP() OWNER TO postgres; 
CREATE TRIGGER TG_BIU_GEO_LOCALTIMESTAMP BEFORE INSERT or UPDATE
   ON geo FOR EACH ROW
   EXECUTE PROCEDURE public.BIU_GEO_LOCALTIMESTAMP();

Espérant que cela réponde à votre problématique.
Saispasfau.

Hors ligne

 

#3 Mon 13 September 2010 10:33

MathieuB
Membre du bureau
Lieu: Montpellier
Date d'inscription: 18 Jan 2006
Messages: 1227
Site web

Re: [postGis] création en "numéro Auto" d'une chaine type YYYYMMDDH24MISSM

Bonjour,

une valeur par défaut pour la colonne dans la définition de la table permet cela :

Code:

CREATE TABLE test
(
  id character varying(17) NOT NULL DEFAULT "substring"(regexp_replace((now())::text, ' |-|:|\\.|\\+'::text, ''::text, 'g'::text), 1, 17),
  valeur text,
  CONSTRAINT test_pk PRIMARY KEY (id)
)
WITH (
  OIDS=FALSE
);

On remplace dans la chaine de caractère renvoyée par la fonction now() les caractères superflu (-:.+) par rien et on en extrait les 17 premiers caractères.

saispasfau : ton trigger modifie la valeur du champ après mise à jour.

CREATE TRIGGER TG_BIU_GEO_LOCALTIMESTAMP BEFORE INSERT or UPDATE
   ON geo FOR EACH ROW


Mathieu BOSSAERT
Association GeoRezo

Hors ligne

 

#4 Mon 13 September 2010 11:36

Nicolas Ribot
Membre
Lieu: Toulouse
Date d'inscription: 9 Sep 2005
Messages: 1538

Re: [postGis] création en "numéro Auto" d'une chaine type YYYYMMDDH24MISSM

Mathieu BOSSAERT a écrit:

Bonjour,

une valeur par défaut pour la colonne dans la définition de la table permet cela :

Code:

CREATE TABLE test
(
  id character varying(17) NOT NULL DEFAULT "substring"(regexp_replace((now())::text, ' |-|:|\\.|\\+'::text, ''::text, 'g'::text), 1, 17),
  valeur text,
  CONSTRAINT test_pk PRIMARY KEY (id)
)
WITH (
  OIDS=FALSE
);

On remplace dans la chaine de caractère renvoyée par la fonction now() les caractères superflu (-:.+) par rien et on en extrait les 17 premiers caractères.

saispasfau : ton trigger modifie la valeur du champ après mise à jour.

CREATE TRIGGER TG_BIU_GEO_LOCALTIMESTAMP BEFORE INSERT or UPDATE
   ON geo FOR EACH ROW


Bonjour

En faisant un replace, sur now(), le resultat sera dependant de la configuration locale de postgresql sur le format de date, et ne garantira pas le format "YYYYMMDDH24MISSM"
Utiliser la fonction la fonction to_char pour controler le format d'une date, en precisant le format (cf http://www.postgresql.org/docs/8.4/inte … ting.html)

Nico

Hors ligne

 

#5 Mon 13 September 2010 12:13

saispasfau
Participant actif
Date d'inscription: 28 Nov 2006
Messages: 62

Re: [postGis] création en "numéro Auto" d'une chaine type YYYYMMDDH24MISSM

Mathieu BOSSAERT a écrit:

saispasfau : ton trigger modifie la valeur du champ après mise à jour.

CREATE TRIGGER TG_BIU_GEO_LOCALTIMESTAMP BEFORE INSERT or UPDATE
       ON geo FOR EACH ROW


Si le trigger ne doit être exécuter qu'à l'insertion, il faut en effet supprimer "or UPDATE".
Saispasfau.

Hors ligne

 

#6 Mon 13 September 2010 23:10

map
Juste Inscrit !
Lieu: cournonsec (34)
Date d'inscription: 24 Feb 2006
Messages: 8

Re: [postGis] création en "numéro Auto" d'une chaine type YYYYMMDDH24MISSM

Merci mathieu...
Merci a saipasfau aussi!

Bon, la mise en pratique :
- execution de la requete "CREATE TABLE" de mathieu :

Code:

CREATE TABLE OBJ_PT
(
  objid character varying(17) NOT NULL DEFAULT "substring"(regexp_replace((now())::text, ' |-|:|\\.|\\+'::text, ''::text, 'g'::text), 1, 17),
  valeur text,
  CONSTRAINT test_pk PRIMARY KEY (objid)
)
WITH (
  OIDS=FALSE
)
;

- execution d'un

Code:

SELECT AddGeometryColumn('obj_pt', 'obj_geom', 2154, 'POINT', 2 );

pour avoir un peu de géométrie, c'est mieux...

resultat :
- creation de table ok...
- addGeom ok...

lorsque j'ouvre qgis et la table OBJ_PT, j'ai le message d'erreur suivant :

There were no columns in the table that were suitable as a qgis key into the table (either a column with a unique index and type int4 or a PostgreSQL oid column.

L'index unique de la colonne 'objid' est inutilisable car QGIS ne supporte pas encore les colonnes autres qu'int4 en tant que clés.


Du coup je m'interroge (encore un peu plus) sur le rôle du

Code:

WITH (
  OIDS=FALSE
)

...

Autre chose... lors de la création de la table, j'ai le message d'avertissement suivant :

ATTENTION:  utilisation non standard de \\ dans une chaîne littérale
LINE 3: ...DEFAULT "substring"(regexp_replace((now())::text, ' |-|:|\\....
                                                             ^
HINT:  Utilisez la syntaxe de chaîne d'échappement pour les antislashs, c'est-à-dire E'\\'.
NOTICE:  CREATE TABLE / PRIMARY KEY créera un index implicite « test_pk » pour la table « test »


Une solution serait-elle de laisser une clef primaire int4 en créant en plus "mon" champ ObjId avec "ma chaine" de 17 caracteres...?

Merci de vos lumières!

Patrick.

Dernière modification par map (Mon 13 September 2010 23:14)

Hors ligne

 

#7 Tue 14 September 2010 09:00

Nicolas Ribot
Membre
Lieu: Toulouse
Date d'inscription: 9 Sep 2005
Messages: 1538

Re: [postGis] création en "numéro Auto" d'une chaine type YYYYMMDDH24MISSM

map a écrit:

Merci mathieu...
Merci a saipasfau aussi!

Bon, la mise en pratique :
- execution de la requete "CREATE TABLE" de mathieu :

Code:

CREATE TABLE OBJ_PT
(
  objid character varying(17) NOT NULL DEFAULT "substring"(regexp_replace((now())::text, ' |-|:|\\.|\\+'::text, ''::text, 'g'::text), 1, 17),
  valeur text,
  CONSTRAINT test_pk PRIMARY KEY (objid)
)
WITH (
  OIDS=FALSE
)
;

- execution d'un

Code:

SELECT AddGeometryColumn('obj_pt', 'obj_geom', 2154, 'POINT', 2 );

pour avoir un peu de géométrie, c'est mieux...

resultat :
- creation de table ok...
- addGeom ok...

lorsque j'ouvre qgis et la table OBJ_PT, j'ai le message d'erreur suivant :

There were no columns in the table that were suitable as a qgis key into the table (either a column with a unique index and type int4 or a PostgreSQL oid column.

L'index unique de la colonne 'objid' est inutilisable car QGIS ne supporte pas encore les colonnes autres qu'int4 en tant que clés.


Du coup je m'interroge (encore un peu plus) sur le rôle du

Code:

WITH (
  OIDS=FALSE
)

...

Autre chose... lors de la création de la table, j'ai le message d'avertissement suivant :

ATTENTION:  utilisation non standard de \\ dans une chaîne littérale
LINE 3: ...DEFAULT "substring"(regexp_replace((now())::text, ' |-|neutral\\....
                                                             ^
HINT:  Utilisez la syntaxe de chaîne d'échappement pour les antislashs, c'est-à-dire E'\\'.
NOTICE:  CREATE TABLE / PRIMARY KEY créera un index implicite « test_pk » pour la table « test »


Une solution serait-elle de laisser une clef primaire int4 en créant en plus "mon" champ ObjId avec "ma chaine" de 17 caracteres...?

Merci de vos lumières!

Patrick.


Bonjour:

Oui, autant creer une cle primaire de type int (serial, meme, elle sera autincrementée) en plus de la colonne metier. Ca sera plus simple
La creation auto des OID a ete supprimée depuis PG 8.1 ou 8.2, pour eviter un pb potentiel si la base contient plus de 4 milliards d'objets. Ca peut etre une solution temporaire.
cette date doit etre utilisée pour identifier les objets uniquement ? si oui, un cle primaire int est plus performante et plus simple a gerer.

Il faut surtout insister aupres de qgis pour resoudre ce bug, ca fait plusieurs années que le ticket est ouvert et non resolu.

Concernant la valeur de la colonne objid, pourquoi s'embeter avec un remplacement de type regexp ? la methode to_char sert précisement a formater les dates:

select to_char(now(), 'YYYYMMDDHH24MISSMS');

Nicolas

Hors ligne

 

#8 Tue 14 September 2010 09:16

MathieuB
Membre du bureau
Lieu: Montpellier
Date d'inscription: 18 Jan 2006
Messages: 1227
Site web

Re: [postGis] création en "numéro Auto" d'une chaine type YYYYMMDDH24MISSM

Nicolas Ribot a écrit:

select to_char(now(), 'YYYYMMDDHH24MISSMS');


Merci Nicolas, en effet, j'avais laissé tombé un peut trop vite à cause d'une erreur de syntaxe : j'avais ...H24... au lieu de ...HH24...

Alors j'en ai profité pour vendre les expressions régulières.

Bonne journée,


Mathieu BOSSAERT
Association GeoRezo

Hors ligne

 

#9 Tue 14 September 2010 12:13

map
Juste Inscrit !
Lieu: cournonsec (34)
Date d'inscription: 24 Feb 2006
Messages: 8

Re: [postGis] création en "numéro Auto" d'une chaine type YYYYMMDDH24MISSM

Bilan :

Code:

CREATE TABLE OBJ_PT
(
  cd serial PRIMARY KEY,
  objid character varying(17) NOT NULL DEFAULT to_char(now(), 'YYYYMMDDHH24MISSMS')
)
WITH (
  OIDS=FALSE
);

puis

Code:

SELECT AddGeometryColumn('obj_pt', 'obj_geom', 2154, 'POINT', 2 );

ensuite ouverture de la table dans QGis, bascule en mode édition, ajout d'un point... et là :
enjoy ;+)
(après une petite inquiétude en fait, lorsque le formulaire d'ajout de données de QGis me présente par défaut dans les champs pré-remplis les fonction non interprétées... mais après validation et contrôle dans la table attrib...no problem)

Merci beaucoup!

Patrick

Hors ligne

 

Pied de page des forums

Powered by FluxBB