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

BDD reseau routier - generer un _id_ a partir de 2 champs texte

Technique - général | BDD reseau routier - generer un _id_ a partir de 2 champs texte

Par bigre le 12/10/2007 - 06:00

Voici le problème :

j'ai une table avec une liste de noeuds routiers, identifié par un code varchar(20).
node_id (varchar(20) primary key) puis d'autres champs descriptifs
A
B
c
CDf
G
SDF
EFG

Une section de route , section_id varchar(40), commence à un noeud et se termine à un autre noeud.

de A à B, de B à C, de C à G, ...

Je dois remplir une table des sections, avec section_id égal à

section_i, node_from, node_to, divers attributs
sectionAB, A, B, longueur, .etc.
sectionBC, B, C
sectionCG, C, G,

Je dois faire un test sur les noeuds, pour ne pas autoriser un utilisateur à définir une section de route qui ferait double emploi : refuser sectionBA, par exemple et générer la valeur du champ section_id, à partir de node_from et node_to, classer dans l'ordre alphabétique....

Me fais-je comprendre ?

comment faire un test sur 2 champs "alphanumérrique", A< B , ?????

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.

Euh

SAS/ = 15 Octobre, 2007 - 09:13

En fait, non...

J'ai l'impression que soit il manque une partie de la question, soit c'est l'explication qui manque de clarté.

Pourriez-vous nous donner les structures des tables ? J'ai cru comprendre que vous souhaitiez faire un test pour que si AB est défini, BA ne puisse pas l'être.

Avez-vous déjà écrit l'ensemble de vos règles de vérification ? Si oui, vous pouvez envisager de les coder sous la forme de règles, de triggers ou de contraintes au niveau des tables.

Sinon, recensez vos contraintes et essayez de les écrire. Vos règles et commandes SQL d'insertion paraîtront plus "évidentes".

Vous pouvez aisni utiliser des commandes d'insertion qui incluent des fonctions ou des tests (par exemple

insérer (ch1||ch2 si ch1< ch2, ch2||ch2 sinon)...

L'ensemble des fonctions de traitement de chaînes de caractères se trouve ici :

http://docs.postgresqlfr.org/8.2/functions-string.html

Pour tester deux chaînes, sous réserve que les locales soient correctement positionnées :

postgres=# select 'A'<'B';
?column?
----------
t
(1 ligne)

Librement,
Stéphane Schildknecht
dalibo
PostgreSQLFr


merci , je vais essayer ...

bigre/ = 20 Octobre, 2007 - 02:35

merci , je vais essayer ...

j'ai aussi découvert l'instruction strcmp ...
la table links contient notamment 3 champs :

link_if, PK, varchar( 20)
node_A, FK, varchar( 8)
node_B, FK

le champ "clef primaire" link_id de la table "links" sera rempli à partir de la table "nodes" dont node_id, est une clef primaire.

et je veux donc générer link_id, à partir de node_A et node_B
et pour que cela soit parlant à l'humain qui travaille, je veux que le contenu de link_id soit la concatenation de node_a et node_B, pour autant que node_a < node_B en classement alphabétique ...
Je vais y arriver ...


BDD reseau routier : function & trigger

bigre/ = 12 Novembre, 2007 - 01:43

A mieux poser la question, je risque d'avoir de meilleures réponses. puis, à force de chercher, on trouve ... presque.

Donc, une table de "nodes", une table de "links" et besoin de déclencher une fonction quand on met à jour la table "links".
Deux étapes : 1) faire la fonction , 2) la déclencher.

Je butte sur le 1)
puis je buterai sur le 2) !

CREATE TABLE links (
linkname character varying(13) NOT NULL,
node_a character varying(6),
node_b character varying(6)
);

CREATE TABLE nodes (
node character varying(6) NOT NULL
);

ALTER TABLE ONLY nodes
ADD CONSTRAINT pknodes PRIMARY KEY (node);
ALTER TABLE ONLY links
ADD CONSTRAINT fk_a FOREIGN KEY (node_a) REFERENCES nodes(node);
ALTER TABLE ONLY links
ADD CONSTRAINT fk_b FOREIGN KEY (node_b) REFERENCES nodes(node);
ALTER TABLE ONLY links
ADD CONSTRAINT pk_links PRIMARY KEY (linkname);

CREATE FUNCTION build_linkname( node_a varchar, node_b varchar, OUT linkname varchar) AS $$
BEGIN
CASE WHEN node_a < node_b
THEN linkname = node_a ||'-'|| node_b
ELSE linkname = node_b ||'-'|| node_a
END;
END;
$$
LANGUAGE 'sql' VOLATILE;

-> ERROR: syntax error at or near "CASE" at character 101

A la loupe ... je ne vois rien !

J'utilise PpqAdmin3 ce qui explique peut être quelques particularités de code ...


Pour la fonction

Jean-Paul Argudo/ = 13 Novembre, 2007 - 12:42

Bonjour,

Je vous propose une version plpgsql corrigée de votre fonction, qui fait appel à une UNION SQL au lieu d'un appel de fonction. Je pense que ça doit être légèrement plus performant:

CREATE or replace FUNCTION build_linkname( node_a varchar, node_b varchar, OUT linkname
varchar) AS $$
BEGIN
select l into linkname from (
select node_a ||'-'|| node_b as l
union
select node_b ||'-'|| node_a) foo
order by l
limit 1;
END;
$$
LANGUAGE 'plpgsql';
jpargudo=# select build_linkname('AA','AZ');
build_linkname
----------------
AA-AZ
(1 row)
Time: 0,220 ms
jpargudo=# select build_linkname('AZ','AA');
build_linkname
----------------
AA-AZ
(1 row)
Time: 0,306 ms

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


CREATE OR REPLACE FUNCTION bu

bigre/ = 16 Novembre, 2007 - 02:53

CREATE OR REPLACE FUNCTION buildlinkname()
RETURNS "trigger" AS
$BODY$
BEGIN
IF new.linkname IS NULL
THEN
IF new.node_a < new.node_b
THEN new.linkname := new.node_a ||'-'||new.node_b;
ELSE new.linkname := new.node_b ||'-'||new.node_a;
END IF;
END IF;
RETURN new;
END;
$BODY$
LANGUAGE 'plpgsql' VOLATILE;

Probleme résolu avec cette fonction et le trigger. Merci à tous ! C'était simple ....


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