Vous n'êtes pas identifié(e).

#101 Re : PSQL » \copy avec des boolean » 26/04/2017 13:37:18

Merci pour votre réponse mais, hélas, les dbs sont identiques.

Indépendamment de la db de destination,  l'export de

                                             Table "public.tblContacts_data"
       Column       |            Type             |                               Modifiers
--------------------+-----------------------------+-----------------------------------------------------------------------
... 
 Credit             | integer                     | default 0
 ...

met un f pour credit. (sa valeur dans la table est 0.)
De plus, faisant l'export et l'import avec le header, je suis sûr de la colonne qui pose problème.

Je trouve ça étrange...

#102 PSQL » \copy avec des boolean » 26/04/2017 11:20:01

Michel Depiesse
Réponses : 8

Bonjour,

Je veux faire un export csc d'une db pg vers une autre db pg. Les deux dbs sont identiques. Elles sont ont créées par restore à partir d'une même backup.

Export :

\copy (select * from "tblContacts_data" where audit_id in (select audit_id from audit_history where table_name = 'tblContacts_data')) to '/home/rubin/Development/Sync/work/tblContacts_data.csv' with csv header;

Import :

\copy ariel."tblContacts_data" from './work/tblContacts_data.csv' with csv header;

j'obtiens

psql:./work/_import_modifs.sql:2: ERROR:  invalid input syntax for integer: "f"
CONTEXT:  COPY tblContacts_data, line 2, column Credit: "f"

le fichier : la valuer posant problème est entre !!!!!!!!!!!!!!!!!

Company,Alpha,ContactID,Title,FirstName,LastName,Qualifications,Address1,Address2,Address3,Town/City,County/State,PostalCode,Country,Telephone1,Mobile,Telephone2,Email1,Email2,Fax,Lead,Website,Salutation,English Salutation,ShipName,ShipAddress1,ShipAddress2,ShipAddress3,ShipTown/City,ShipCounty/State,ShipPostalCode,VatNr,EtNr,JbtNr,FinRating,TurnOver $,Memo,COD,Bank,BankAddress1,BankAddress2,BankAddress3,BankTown/City,BankCounty/State,BankPostalCode,BankCountry,AccountNr,Swift,Commission Base,!!!!!!!!!!!!!!!Credit!!!!!!!!!!!!!!,Currency,RSC-Link,ADDED,RIA_NR,ANNICK_NR,Last_Contacted,ContactCycle,UPDATED,SIMIL,KYC,ADC_NR,audit_id,deleted_by,Active,DateAdded,deleted_when

Mi corp,MIMI,16947,,Mi,Mic,prog,str1,str2,str3,Brussels,Beijing,1190,BY,0998898,00998776,,e@kkdze.bbe,,66556,JCK,,Dear Sirs,Ole,,,,,,,,,,,,,,f,,,,,,,,,,,0,0,,!!!!!!!!!!!!!!!f!!!!!!!!!!!!!!,,0,0,,60,f,,,0,8868,,f,2017-04-25,

Dans la db source, la colonne credit (integer) = 0.

Je ne comprends pas pourquoi, \copy me la transforme en f.

Je suis franchement navré de porter à votre connaissance un problème aussi horrible.

Merci pour votre attention

#103 Migration » Write conflict : This record has been changed by another user.. » 10/04/2017 13:57:35

Michel Depiesse
Réponses : 0

Bonjour,

Nous avons migré une application Access vers PostgreSQL

Le front-end en Access utilise des linked tables sur des views.

Quand le front-end veut mettre à jour des records créés avant la migration, il n'y a pas de problèmes.

Mais si nous cherchons à faire un update sur un record crée depuis lors, nous recevons le message :

              Write conflict

This record has been changed by another user since you started editing it. 
.../...

Le bouton "Save record" est inactif.

Ce qui est le plus étrange, c'est que ça n'arrive que sur une table.

Que faire ?

Merci pour votre attention

#104 Re : PL/pgSQL » dblink ou postgres fdw ou ? » 10/04/2017 09:33:15

Un grand merci à vous deux pour ces précisions.

@Guillaume : pourriez-vous me donner un lien avec un exemple ? car je voudrais éviter de mettre un username/password dans une fonction.

Bonne journée à vous deux

#105 Re : PL/pgSQL » dblink ou postgres fdw ou ? » 07/04/2017 14:05:06

je joins le query à toutes fins utiles :

 select
                public.dblink_connect('link2contacts', 'hostaddr=x.x.x.x port=5432 dbname=contacts user=x  password=xxx');


        with
                "qryMailPrep"
                as (
                        select
                                case when "gc_To" like '%rubin%' then 'RECEIVE' else 'SENT' end as "SENT_RECEIVE",
                                case when "gc_To" like '%rubin%' then "gc_SenderEmailAddress" else "gc_To" end as "EMAIL",
                                "Mail".*
                        from
                                "Mail"
                ),
                "tblContacts"
                as (
                        select
                                *
                        from
                                dblink('link2contacts', 'select "Alpha", "ContactID", "Email1", "Email2" from "tblContacts"')
                                AS t (   "Alpha"        varchar
                                        ,"ContactID"    integer
                                        ,"Email1"       varchar
                                        ,"Email2"       varchar
                                        )
                ),
                "tblContactsSubs"
                as (
                        select
                                *
                        from
                                dblink('link2contacts', 'select "ContactID", "Email1" from "tblContactsSubs"')
                                AS t (   "ContactID"    integer
                                        ,"Email1"       varchar
                                        )
                )
        select
                "tblContacts"."Alpha", "tblContacts"."ContactID", "qryMailPrep".*
        from
                "qryMailPrep" INNER JOIN "tblContacts" on "qryMailPrep"."EMAIL" = "tblContacts"."Email1"
        union all
        select
                "tblContacts"."Alpha", "tblContacts"."ContactID", "qryMailPrep".*
        from
                "qryMailPrep" INNER JOIN "tblContacts" on "qryMailPrep"."EMAIL" = "tblContacts"."Email2"
        union all
        select
                "tblContacts"."Alpha", "tblContacts"."ContactID", "qryMailPrep".*
        from
                "qryMailPrep" INNER JOIN ("tblContacts" INNER JOIN "tblContactsSubs"
                                        on "tblContacts"."ContactID" = "tblContactsSubs"."ContactID")
                        on "qryMailPrep"."EMAIL" = "tblContactsSubs"."Email1";

        SELECT dblink_disconnect('link2contacts');

#106 PL/pgSQL » dblink ou postgres fdw ou ? » 07/04/2017 13:52:56

Michel Depiesse
Réponses : 5

Bonjour,

Je dois écrire une fonction qui fait un select compliqué sur 3 tables appartenant à deux bases de données.

J'avais commencé avec dblink mais...

create or replace function query_mail returns table( plein de colonnes) as $$
begin

       select public.dblink_connect('...

       return query select ... (un truc très compliqué)

       dblink_disconnect('...

mais  le disconnect ne sera jamais atteint, bien sûr.

Y a-t-il moyen de faire un dblink permanent ?

Ou vaut-il mieux utiliser un autre mécanisme que dblink ?

Merci pour votre attention,
mchl

#107 Re : PgAdmin3 » Problème avec le restore » 05/04/2017 14:56:48

Merci.

Par ailleurs, la migration Access -> pg (avec le front-end en Access) marche bien.

Le client roucoule.

Un grand merci à tous ceux qui ont pris le temps de me répondre.

Une bonne journée à tous

#108 PgAdmin3 » Problème avec le restore » 04/04/2017 11:52:26

Michel Depiesse
Réponses : 2

Bonjour,

J'ai fait un backup avec :

pg_dump my_db -U zglutsh

et ensuite, j'aimerais faire un restore en pgadmin3.
J'ai créé un db test_restore dont le owner est zglutsh, un role qui a tous les droits.
Mais le bouton 'Restore' reste inactif.
Que faire ?
Merci pour votre attention.

#110 Général » psql n'affiche plus les résultats des selects » 30/03/2017 10:36:54

Michel Depiesse
Réponses : 1

Bonjour,

Je ne sais pas ce qui se passe. Depuis le dernier le create database que j'ai fait, je ne sais plus faire de select en psql,

Voici le message en psql

contacts=> select from public."tblActions_data" where audit_id = 3508;
--
(1 row)

ou encore

contacts=> select from public."tblActions_data";


beaucoup de lignes blanches

--
(3508 rows)

Les tables sont pourtant populées. Je vois le contenu quand je fait un View data->View all rows ou quand je fais des queries en pgadmin.

J'ai le même coup si je me connecte en psql avec -U postgres ou -U <le owner de la db>

Quel flip !


Merci pour votre attention

#111 Général » psql n'affiche plus les résultats des selects » 30/03/2017 10:36:40

Michel Depiesse
Réponses : 0

Bonjour,

Je ne sais pas ce qui se passe. Depuis le dernier le create database que j'ai fait, je ne sais plus faire de select en psql,

Voici le message en psql

contacts=> select from public."tblActions_data" where audit_id = 3508;
--
(1 row)

ou encore

contacts=> select from public."tblActions_data";


beaucoup de lignes blanches

--
(3508 rows)

Les tables sont pourtant populées. Je vois le contenu quand je fait un View data->View all rows ou quand je fais des queries en pgadmin.

J'ai le même coup si je me connecte en psql avec -U postgres ou -U <le owner de la db>

Quel flip !


Merci pour votre attention

#113 PgAdmin3 » Se connecter sur pgadmin3 avec un username/password » 29/03/2017 09:47:21

Michel Depiesse
Réponses : 2

Bonjour,

De la même manière que l'on peut faire psql -U gino ou psql -U aldo, j'aimerais avoir des sessions pgadmin avec des users différents.

Comme faire ?

Merci pour votre attention et bonne journée à vous

#114 PL/pgSQL » exception when others » 20/03/2017 10:47:12

Michel Depiesse
Réponses : 1

Bonjour,

Faisant beaucoup de sql dynamique, j'ai dans toutes mes fonctions une clause "exception when others".

J'aimerais écrire "exception when others then write2log(sqlcmd : sqlerrm)" où sqlcmd est la commande sql qui a déclenché l'exception.

Y a-t-il en PL/pgSQL une variable jouant le rôle de sqlcmd ?

Merci

#115 Re : PL/pgSQL » Comment écrire dans un fichier à partir d'une fonction » 13/03/2017 10:44:50

Un grand merci pour cet éclaircissement.

J'ai résolu mon problème avec bash mais je reconnais que cette solution passablement baroque pourrait choquer certains esprits épris de classicisme :

#!/bin/bash

psql contacts -qtA -c > tables_pk.txt "select
        kc.table_name || ',' || kc.column_name
from
        information_schema.table_constraints            tc
join
        information_schema.key_column_usage             kc
on
        tc.table_name = kc.table_name
and
        kc.constraint_name = tc.constraint_name
where
        tc.constraint_type = 'PRIMARY KEY'
and
        tc.constraint_schema = 'public'
and
        tc.table_name like 'tbl%data'
order by
        1;"

tables_pk="tables_pk.txt"

while IFS="," read -r table_name pk_name 
do
	echo
	echo
	echo "create or replace function sync.update_$table_name(schema_name varchar, r audit_history) returns void as \$\$"
	echo
	echo "declare stmt varchar; info varchar; pk_name varchar; this_pk integer;"
	echo
	echo "begin"
	echo
	echo "execute format('select \"%s\" from public.\"$table_name\" where audit_id = \$1','$pk_name')
		into this_pk
                using r.audit_id;"
	echo
	echo "if this_pk is null then

                info := format('In update : no record found in \"$table_name\" where audit_id = %s', r.audit_id);

                insert into sync.log values (schema_name, info);
		
		return;"

	echo "end if;"
	echo
	echo "stmt := 'update public.\"$table_name\" as p set"

	set_clause=`psql -qtA contacts -c  " 
        	select
                           '\"' 
			|| c.column_name 
			|| '\"' 
			|| ' = ' 
			|| 's.' 
			|| '\"' 
			|| c.column_name 
			|| '\"' 
			|| ','
		from 
			information_schema.tables as t 
		join
			information_schema.columns as c on t.table_name = c.table_name 
		where
			t.table_schema = 'public' 
		and 
			c.table_schema = 'public' 
		and 
			c.column_name not in ( 
				select
					kcu.column_name
				from 
					information_schema.table_constraints as tc 
				join 
					information_schema.key_column_usage as kcu 
						on tc.constraint_name = kcu.constraint_name
				join 
					information_schema.constraint_column_usage as ccu 
						on ccu.constraint_name = tc.constraint_name
				where 
					(constraint_type = 'FOREIGN KEY' or constraint_type = 'PRIMARY KEY')
				and 
					tc.table_name = '$table_name'
			)
		and
			c.column_name != 'audit_id'
		and
                        t.table_name = '$table_name'"`

	echo "${set_clause::-1}"	
	echo "';"
	echo
	echo "stmt := stmt || ' from %s.\"$table_name\" as s where p.\"$pk_name\" = s.\"$pk_name\" and p.\"$pk_name\" = \$1';" 
	echo
	echo "execute format(stmt, schema_name) using this_pk;"
	echo
	echo "insert into sync.log values(schema_name, 'Updated \"$table_name\" for \"$pk_name\" = ' || this_pk);"
	echo
	echo "perform sync.update_committed(schema_name, r.id_audit_history);";
	echo
	echo "exception when others then insert into sync.log values(schema_name ,sqlerrm);"
	echo
	echo "end \$\$ language 'plpgsql';"
	echo

done < "$tables_pk"

#116 Re : PL/pgSQL » update massif » 10/03/2017 12:46:17

Finalement, j'ai écrit une fonction update par table.
Pour ce faire, j'ai écrit ce script de 83 lignes qui génère les 1488 lignes de code.

!/bin/bash 

tables_pk="tables_pk.txt" 
while IFS="," read -r table_name pk_name  
do 
       echo 
       echo "create or replace function sync.update_$table_name(schema_name varchar, audit_id bigint) returns void as \$\$" 
       echo 
       echo "declare stmt varchar; info varchar; pk_name varchar; this_pk integer;" 
       echo 
       echo "begin" 
       echo 
       echo 
       echo "execute format('select \"%s\" from public.\"$table_name\" where audit_id = \$1','$pk_name') 
               into this_pk 
               using audit_id;" 
       echo 
       echo "if this_pk is null then 

               info := format('In update : no record found in $table_name where audit_id = %s', audit_id); 

               insert into sync.log values (schema_name, info); 
                
               return;" 

       echo "end if;" 
       echo 
       echo "stmt := 'update public.\"$table_name\" as p set" 

       set_clause=`psql -qtA contacts -c  "  
               select 
                          '\"'  
                       || c.column_name  
                       || '\"' 
                       || '\"'  
                       || ' = '  
                       || 's.'  
                       || '\"'  
                       || c.column_name  
                       || '\"'  
                       || ',' 
               from  
                       information_schema.tables as t  
               join 
                       information_schema.columns as c on t.table_name = c.table_name  
               where 
                       t.table_schema = 'public'  
               and  
                       c.table_schema = 'public'  
               and  
                       c.column_name not in (  
                               select 
                                       kcu.column_name 
                               from  
                                       information_schema.table_constraints as tc  
                               join  
                                       information_schema.key_column_usage as kcu  
                                               on tc.constraint_name = kcu.constraint_name 
                               join  
                                       information_schema.constraint_column_usage as ccu  
                                               on ccu.constraint_name = tc.constraint_name 
                               where  
                                       (constraint_type = 'FOREIGN KEY' or constraint_type = 'PRIMARY KEY') 
                               and  
                                       tc.table_name = '$table_name' 
                       ) 
               and 
                       c.column_name != 'audit_id'
               and 
                       t.table_name = '$table_name'"` 

       echo "${set_clause::-1}"         
       echo "';" 
       echo 
       echo "stmt := stmt || ' from %s.\"$table_name\" as s where p.\"$pk_name\" = \$1';"  
       echo 
       echo "execute format(stmt, schema_name, pk_name) using this_pk;" 
       echo 
       echo "exception when others then insert into sync.log values(schema_name ,sqlerrm);" 
       echo 
       echo "end \$\$ language 'plpgsql';" 
       echo 

done < "$tables_pk"

Bon week-end

#117 PL/pgSQL » Comment écrire dans un fichier à partir d'une fonction » 09/03/2017 10:34:58

Michel Depiesse
Réponses : 2

Bonjour,

J'écris souvent des scripts meta-sql comme celui-ci :

select
       ',' || c.column_name || ' = ' || 's.' || c.column_name
from
        information_schema.tables as t
join
        information_schema.columns as c on t.table_name = c.table_name
join
        information_schema.table_constraints as tc on tc.table_name = t.table_name
join
        information_schema.key_column_usage as kcu on tc.constraint_name = kcu.constraint_name
join
        information_schema.constraint_column_usage as ccu on ccu.constraint_name = tc.constraint_name
where
        (constraint_type != 'FOREIGN KEY' and constraint_type != 'PRIMARY KEY')
and
        t.table_schema = 'public'
and
        c.table_schema = 'public'
and
        t.table_name like 'tblActions_data'
order by
        1;

qui me donne les clauses set pour un update.

J'aimerais mettre ces scripts dans des fonctions, mais je n'arrive pas à trouver comment peut-on écrire dans un fichier texte à partir de pgplsql.

Pourriez-vous me donner une indication ?

Merci pour votre attention.

#118 Re : PL/pgSQL » update massif » 08/03/2017 19:50:28

Merci pour votre réponse.

Nous avons une db centrale.

On la copie sur des tablettes pour les agents qui parcourent le monde.

Quand ils reviennent, on met à jour la db centrale à partir de leur db modifiée en suivant des business rules spécifiques à la firme.

Voilà...

Je suis, bien sûr, ouvert à toute suggestion.

Bonne soirée à vous et à tous les dalibiens.

#119 PL/pgSQL » update massif » 08/03/2017 17:56:17

Michel Depiesse
Réponses : 3

Bonjour,

Je dois écrire une fonction qui fasse un update dans les tables du schema s à partir du schema t.

Je dois donc écrire pour chaque table

UPDATE 
    s.table_a AS s 
SET 
    col1 = t.col1
FROM 
    t.table_a AS t
WHERE 
    t.id = s.id;

Mais étant paresseux, j'aimerais ne pas devoir écrire autant de clauses SET qu'il y de colonnes dans les 80 tables de l'application.

Y a-t-il un procédé pg pour updater tous les champs qui ne sont pas pk et fk ?

Sinon, je générerais la function par un script meta-sql.

Merci pour votre attention.

#120 Re : PL/pgSQL » Trigger + variable old. + sql dynamique » 03/03/2017 11:06:14

@gleu

Merci pour votre réponse.

A/ Si on passe au paradigme no-delete, il y est logique, me semble-t-il, de munir chaque table d'un champ qui indique si le record a été effacé. Je ne vois pas ce qui suscite votre étonnement. Une autre solution consisterait à alimenter une base de données ayant les mêmes tables avec les records effacés de la base de données de production.

B/ En ce qui concerne la question du marquage des enregistrements ayant une clé de référence vers l'enregistrement effacé, il me semble que ce n'est pas un problème important : si l'application cliente ne voit pas l'enregistrement racine, elle ne cherchera pas à voir les enregistrements branches. Il faut prévoir un utilitaire qui liste les enregistrements déracinés et leur donne une terre d'asile.

C/ Le paradigme no-delete a ses détracteurs mais il me semble justifié car 1/ collecter des données et les enregister de manière structurée coûte cher, 2/ conserver ces données ne coûte quasiment rien et 3/ effacer des données qui n'auraient pas dû l'être coûte quelquefois très cher.

D/ Il est dommage que les tuples old et new ne veulent pas se soumettre aux mêmes règles que les autres objects.

@DanielVerite
Merci pour votre réponse
Vu la controverse qui vient de s'élever entre deux spécialistes, j'applique la loi de Murphy : "Si ça risque de ne pas marcher, ça ne marchera pas". smile

@gleu et @DanielVerite
Merci à tous deux pour votre aide et bon week-end

#121 Re : PL/pgSQL » Trigger + variable old. + sql dynamique » 02/03/2017 18:12:40

Merci à vous deux.

Donc, si je vous comprends bien, il n'y a pas moyen de faire un old.pk_name où pk_name est calculé par la fonction.

Encore une petite question.

L'inconvénient du soft delete est que les records fils (dont la fk pointe vers la pk du record effacé) ne sont pas marqués. Y a-t-il une solution simple ? Le on update on cascade ne semble pas convenir.

Merci pour votre attention et bonne fin de soirée

#122 Re : PL/pgSQL » Trigger + variable old. + sql dynamique » 02/03/2017 18:07:15

Génial ! Je vais tester ça dés que possible.

Un grand merci à vous,

#123 Re : PL/pgSQL » trigger or rule on delete » 02/03/2017 17:22:15

Merci pour votre réponse qui confirme mon impression.

#124 Re : PL/pgSQL » Trigger + variable old. + sql dynamique » 02/03/2017 13:22:42

En fait ça ne marche pas. Mon trigger efface tous les enregistrements de la table.

Je vais essayer en ajoutant à stmt ' where ' || nom_de_la_pk || ' = $1'.

A+

#125 Re : PL/pgSQL » Trigger + variable old. + sql dynamique » 02/03/2017 10:39:36

Bonjour,

Par delete logique, je désigne le fait de marquer l'enregistrement par un champ 'deleted' et de ne pas l'effacer par un delete. Et l'application front-end (en Access VBA) a accès à des vues select ... where deleted is null.

La méthodologie du no delete a des partisans et des déracteurs. Une autre solution consisterait à copier les enregistrements effacés dans une autre base de données ayant les mêmes tables.


Au sujet de la question précédente, je m'en suis tiré avec :

        stmt :=    'update public.'
                || quote_ident(TG_TABLE_NAME)
                || ' set deleted_when = now() ,deleted_by = '
                || ''''
                || current_user
                || '''';


        case TG_TABLE_NAME 
                when 'tblActions' then execute stmt using old."ActionID";
                when 'tblBlankRows' then execute stmt using old."BlankRowID";
                .../...

Je n'ai pas trouvé le moyen de sélectionner la pk dans le tuple old comme décrit dans le post précédent.

Cette fonction est activée par un trigger before delete.

Merci pour votre attention,
Mchl

Pied de page des forums

Propulsé par FluxBB