Vous n'êtes pas identifié(e).
Pages : 1
Impeccable, que dire de + sinon merci
J'ai pris la première solution.
Carole
Re,
J'ai fait la modif comme ceci
CREATE OR REPLACE FUNCTION lower_username()
RETURNS trigger AS
$BODY$DECLARE
tmp VARCHAR;
cont integer;
BEGIN
NEW."firstName" := initcap(NEW."firstName");
NEW."lastName" := initcap(NEW."lastName");
NEW.username := lower(NEW."firstName"||'.'||NEW."lastName");
SELECT max(username) into tmp FROM users where "firstName" = NEW."firstName" and "lastName" = NEW."lastName";
IF tmp IS NULL THEN
-- ne rien faire
ELSIF tmp = NEW.username THEN
NEW.username :=lower(NEW."firstName"||'.'||NEW."lastName"||'1');
ELSE
SELECT MAX(TRIM(username,(NEW."firstName"||'.'||NEW."lastName"))::INT)+1 INTO cont FROM users where "firstName" = NEW."firstName" and "lastName" = NEW."lastName" and username != NEW.username;
NEW.username := NEW."firstName"||'.'||NEW."lastName"||cont::TEXT;
END IF;
RETURN NEW;
END;
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100;
ALTER FUNCTION concat_username() OWNER TO nuxeodm;
mais cela me génère cette erreur à l'execution du trigger insert
[WARNING ] INSERT INTO users(
corps, section, article, n_emploi, type_candidature, civilite, "lastName", nom_matrimonial, "firstName", n_candidat, email)
SELECT * FROM users_test
WHERE not exists (
SELECT n_candidat FROM users where users.n_candidat=users_test.n_candidat
)
ERREUR: syntaxe en entrée invalide pour l'entier : « zap.zop1 »
CONTEXT: instruction SQL « SELECT MAX(TRIM(username,(NEW."firstName"||'.'||NEW."lastName"))::INT)+1 FROM users where "firstName" = NEW."firstName" and "lastName" = NEW."lastName" and username != NEW.username »
PL/pgSQL function "lower_username" line 14 at instruction SQL
Me revoilou avec encore une petite question.
Comme vous me l'aviez conseillé, il faudrait que le username généré soit tout le temps un minuscule, peut importe si le lastname et le firstname est en majuscule ou pas.
j'ai essayé ceci avec la fonction lower():
CREATE OR REPLACE FUNCTION plip()
RETURNS TRIGGER AS
$$
DECLARE
tmp VARCHAR;
cont integer;
BEGIN
NEW.firstname := initcap(NEW.firstname);
NEW.lastname := initcap(NEW.lastname);
NEW.lower(username) := NEW.firstname||'.'||NEW.lastname;
SELECT max(username) into tmp FROM plop where firstname = NEW.firstname and lastname = NEW.lastname;
IF tmp IS NULL THEN
-- ne rien faire
ELSIF tmp = NEW.username THEN
NEW.lower(username) := NEW.firstname||'.'||NEW.lastname||1;
ELSE
SELECT MAX(TRIM(username,(NEW.firstname||'.'||NEW.lastname))::INT)+1 INTO cont FROM plop where firstname = NEW.firstname and lastname = NEW.lastname and username != NEW.username;
NEW.lower(username) := NEW.firstname||'.'||NEW.lastname||cont;
END IF;
RETURN NEW;
END
$$
LANGUAGE PLPGSQL;
entre autres choses mais cela ne fonctionne pas. Où dois je insérer la fonction svp?
Carole
Merci pour votre réponse.
J'ai effectué la modif et j'obtiens l'erreur
ERREUR: n'a pas pu ouvrir le fichier « Z:/1Commun/NUXEO 2011/users.csv » pour
une lecture : No such file or directory
en fait je pense que cela ne fonctionne pas du fait qu'il s'agit d'un lecteur réseau.
Bonjour,
Je rencontre un soucis avec psql dans une fenetre dos.
Je veux utiliser la commande "copy from" lorsque le chemin du fichier csv que je souhaite pointer est sur le disque C: cela fonctionne, par contre j'ai besoin de copier les données d' un csv situé sur un lecteur que j'ai monté (Z:) avec un connecteur réseau et je n'arrive pas à faire fonctionner le copy from.
COPY users_temp from 'Z:1Commun\\NUXEO 2011\\users.csv' using delimiters ',' WITH CSV HEADER;
J'obtiens cette erreur:
ATTENTION: utilisation non standard de \\ dans une chaîne littérale
LIGNE 1 : COPY users_temp from 'Z:\\1Commun\\NUXEO 2011\\users.csv' us...
^
ASTUCE : Utilisez la syntaxe de chaîne d'échappement pour les antislashs, c'es
t-Ã -dire E'\\'.
ERREUR: n'a pas pu ouvrir le fichier « Z:\1Commun\NUXEO 2011\users.csv » pour
une lecture : No such file or directory
Pourriez vous m'aider svp?
Cordialement
Carole
Oui dans la table users, il peut y avoir des doublons sur le nom, prenom et c'est pour cela que le trigger générant des logins unique de type 'prenom.nom[1234...]' est nécessaire. Par contre dans les tables users et users_tampon il y a d'autres champs aussi, dont un 'n_candidat' qui est unique, donc je pensais que comme ce n° etait different, lors de l'insert un doublon de login ne sera pas généré.
Voici l'insert que je fais:
Oui dans la table users, il peut y avoir des doublons sur le nom, prenom et c'est pour cela que le trigger générant des logins unique de type 'prenom.nom[1234...]' est nécessaire. Par contre dans les tables users et users_tampon il y a d'autres champs aussi, dont un 'n_candidat' qui est unique, donc je pensais que comme ce n° etait different, lors de l'insert un doublon de login ne sera pas généré.
Lors de l'insert dans la table users je mets une condition 'WHERE not exists users.n_candidat=users_tampon.n_candidat'
Par contre je n'ai pas pu encore le tester en situation car mon trigger faisant le "truncate before copy" ne fonctionne pas.
voici ce que j'ai mis:
CREATE TRIGGER suppression
BEFORE INSERT OR UPDATE
ON users_tampon
FOR EACH STATEMENT
EXECUTE PROCEDURE vider_table(E'\\x');
CREATE OR REPLACE FUNCTION vider_table()
RETURNS trigger AS
$BODY$
BEGIN
delete from users_tampon;
END;
J'ai essaye du coup en faisant un "delete from " à la place du truncate mais sans succès.
Bonjour,
Tout d'abord je vous remercie pour votre aide.
En fait il n'y pas pas d'écriture sur le csv directement. Le secrétariat possède le fichier sur un espace propre et en effectue une copie sur un espace partagé avec le serveur nuxeo à la fin de la journée. Ensuite dans la soirée, je lancerais un batch effectuant la "copy" des données du csv sur la base, dans une table tampon. Suivant vos conseils je vais faire un truncate de la table tampon avant que les données soient copiées (before copy c'est bien celà non?) et ensuite faire un "insert or ignore" de la table tampon vers la table "users" (où j'inclue 2 triggers qui génèrent un username + un password lors de l'insert).
Cela parait pas mal non?
Carole
Bonjour,
J'ai besoin d'alimenter une des tables de ma bdd via un fichier csv qui est alimenté au fur et à mesure.
Lorsque j'effectue la commande
COPY users_test from 'C://users.csv' using delimiters ',' WITH CSV HEADER;
l'insertion des données dans la table users_test s'effectue mais mon soucis est que les données se rajoutent dans la table à chaque "copy", effectuant donc des doublons.
Si je rajoute une contrainte unique sur un champ de la table "users_test", alors la copy ne s'effectue pas car elle n'effectue pas un "insert or ignore".
sauriez vous comment je pourrais arriver à résoudre ce problème svp?
Je n'ai pas trouvé dans l'aide sur la commande "copy" pour l'instant. Si cela n'est pas possible avec cette commande, est ce qu'il existe une autre commande qui me permet d'obtenir le résultat souhaité?
amicalement
Carole
en local je teste sur la version p de postgres.
sur le serveur c'est la version 8.4 qui est installée.
J'ai testé le nouveau code et c'est tout simplement parfait. Merci beaucoup de tout coeur.
Carole
Re,
J'ai essayé le nouveau code amélioré mais l'exécution me génère l'erreur:
ERREUR: l'opérateur n'est pas unique : text || integer
LINE 1: SELECT NEW.firstName||'.'||NEW.lastName || 1
^
HINT: N'a pas pu choisir un meilleur candidat pour l'opérateur. Vous devez ajouter une
conversion explicite de type.
Rholalalal MERCI vraiment beaucoup. C'est extra.
Pour un premier trigger tu assures .
Avec la commande copy cela ne marchait pas puisque dans le csv il n'y a pas de colonne "username" mais du coup je le fais en 2 fois : d'abord
- copy csv to users_temp
puis insertion des données de users_temp dans users (et génération auto du username donc)
Trop contente
Carole
Bonjour et merci à vous 2 pour votre aide. grace à vous je commence à voir le bout du tunnel.
J'ai inséré le code en rajoutant un
group by firstName, lastName
après le select car cela me renvoyait une erreur lors de l'exécution.
Lorsque je fait un
INSERT INTO users(lastName, firstName) VALUES ('DUPON','TOTO');
Lors du premier insert, le username se génère parfaitement avec la valeur TOTO.DUPON
Par contre si je retente une autre insertion avec les memes valeurs, je n'obtiens pas TOTO.DUPON1 , TOTO.DUPON2, TOTO.DUPON3 ... mais cette erreur :
ERREUR: syntaxe en entrée invalide pour l'entier : « »
Carole
Oui le username est stocké dans la table plop.
Il permet aux utilisateurs de s'authentifier sur l'appli web en l'occurence Nuxeo.
Carole
tout d'abord merci pour m'aider à résoudre mon souci. Je ne sais pas si j'ai mal expliqué, ce qui est fort possible, ou si je ne comprends pas comment mettre en application ton exemple pour mon cas.
En fait la valeur username n'est pas inséré par ma requête d'insert. Le username est généré automatiquement via la fonction trigger.
CREATE TABLE plop( firstname VARCHAR, lastname VARCHAR, username VARCHAR);
INSERT INTO plop VALUES ('Jean','Dupont'),('Jean','Dupont'),('Jean','Dupont');
en fait j'insère les données via un fichier csv où le username ne figure pas. Et donc le fait de faire générer automatiquement le username via le trigger serait super pour çà.
du coup je ne suis pas arrivée à adapter ton script. Désolée d'être pénible et de t'embêter encore.
Désolée aussi pour le code dans l'image mais je n'ai pas eu le choix car le pare feu de ma boite bloquait l'envoi du code sur le forum.
Carole
Oui en fait il faudrait que jean.dupont2 soit crée et que l'incrément soit fait automatiquement par rapport au dernier chiffre inséré.... c'est encore + galère que ce que ce que je pensais.
Bonjour,
Je bloque sur un problème que je me permets de vous soumettre.
J'ai une table 'users' dans laquelle j'ai un champ 'username' avec un trigger "before insert" dont le résultat concatène la valeur de 2 autre champs 'firstname' et 'lastname'.
BEGIN
NEW.username=NEW.firstName ||'.' ||NEW.lastName ;
RETURN NEW;
END;
Ceci fonctionne bien. Par contre je souhaite que avant chaque insert soit testé dans la table l'existance d'un meme champ 'lastname' et 'firstname' afin qu'il n'y ait pas de doublon pour les username. Il faudrait donc que si une ligne possède déja les mêmes valeurs 'lastname' et 'firstname' que celles qui vont être insérées, le username généré soit 'firstname'.'lastname'+ un chiffre incrémenté (exemple : toto.dupont1).
J'ai essayé ce genre de code ci dessous mais cela ne fonctionne pas, pourriez vous m'aider svp ?
carole
Pages : 1