Vous n'êtes pas identifié(e).
c'est tout bête , en fait il suffisait juste de faire:
gzip -c -d /monfichier.gz | psql -d madb -c " COPY ma_table FROM stdin with delimiter ';' "
je ne sais pas pourquoi sa n'avait pas marché avant
Je ne pense pas que la doc soit assez précise
J'ai trouvé pour l'export qu'il y a psql -c "COPY foo_table TO stdout DELIMITER ',' CSV HEADER" \
| gzip > foo_table.csv.gz
il me faudrait l'équivalent mais pour l'import
Bonjour. Je fais des export/import d'une db très volumineuse donc je crée un fichier gz contenant mon fichier avec les données , je fais l'export avec le spool de sqlplus , mais comment faire l'import avec COPY FROM STDIN?
j'ai beau chercher sur le net je ne trouve pas grand chose. Merci
Autant pour moi j'ai mal lu ><. Et avec un overlay(',' placing '.') ou quelque chose dans ce genre ?
Il me semble que dans mes cours sql il y a une autre fonction.
Tu utilise un délimiteur quand tu fais un copy ma_table to ...? si ce n'est pas le cas rajoute WITH DELIMITER ";"
C'est exactement la même table , et il y a un oid , ou plutôt un rowid , d'où le WHERE OID = ROWIDS; car à la base c'était WHERE ROWID = ROWIDS; enfin bref. Je testerai demain si possible avec le contenu total de la base oracle , soit des millions de lignes et je verrais le résultat. En tout cas merci beaucoup pour votre patiente et votre aide.
PS: 72000 insert en 591445ms ( soit 9,8min ) au lieu de ~27min
Pourquoi n'y était-il pas de base sur le script oracle alors? Il n'y en a pas besoin?
Désolé mais bon je débute , et même après avoir lu la doc sur l'index j'ai un peu de mal à accrocher.
Justement c'est là où c'est drôle , car il n'y en a pas. Aucune clé primaire , aucune contrainte d'unicité , les tables temporaires sont juste des colonnes qu'on insérera dans la table principale en ajoutant une colonne qui contiendra la clé primaire , donc inutile pour moi à ce stade.
Pour l'index j'ai mis CREATE INDEX I_TMP_ENTCDECLI on TMP_ENTCDECLI(NUM_ETT, NUM_BU, NUM_TYPETT, NUM_CDECLI, DAT_CREPROD,OID).
La fonction vient juste de finir , cela m'a pris 9,5min , sa moins de la moitié du temps initial.
Le problème vient du WHERE OID = ROWIDS; mais comment faire autrement? Je dois bien faire un update ligne par ligne , et sur les bonnes tant qu'à faire.
Effectivement le problème vient de l'update , j'ai exécuté ma fonction sans , le résultat est de 1 sec.
Le seul index que j'ai est celui de la fonction qui crée au début et supprimé à la fin.
Pour l'oid il y était de base donc je préfère le laisser au moins pour l'instant , s'il faut faire sans je verrai plus tard si je peux l'enlever.
Et pour le explain j'obtiens:
Merge Join (cost=44791.38..47440.74 rows=119009 width=139)
Merge Cond: ((t_ref_ett.cod_typett = tmp_entcdecli.num_typett) AND (t_ref_ett.num_bu = tmp_entcdecli.num_bu) AND (t_ref_ett.num_ett = tmp_entcdecli.num_ett))
-> Sort (cost=17.26..17.74 rows=193 width=39)
Sort Key: t_ref_ett.cod_typett, t_ref_ett.num_bu, t_ref_ett.num_ett
-> Seq Scan on t_ref_ett (cost=0.00..9.93 rows=193 width=39)
-> Sort (cost=44774.13..45138.59 rows=145787 width=160)
Sort Key: tmp_entcdecli.num_typett, tmp_entcdecli.num_bu, tmp_entcdecli.num_ett
-> Seq Scan on tmp_entcdecli (cost=0.00..8351.34 rows=145787 width=160)
Filter: (etat_int <> 1::numeric)
Voici mon code très barbare , la fonction met 26min pour s'executer , suite à cela dans ma table temporaire les colonnes concerné auront comme etat_int la valeur 3 , je fais donc un copy ... to , puis en copy ... from (3sec au total pour 72000 , les 2 copy au total ) mais le curseur est beaucoup trop long. Si vous avez besoin d'autres infos...Par contre je ne pense pas que je laisserai le code longtemps sur le forum.
/* delete */
En essayant une autre méthode j'ai remarqué que mon cursor met 20min au moins les 25 pour se créer , et le lire ligne par ligne puis de faire un update à chaque ligne d'une colonne état qui par la suite servira à savoir s'il faut faire un traitement sur cette ligne. Est-ce normal que ce soit aussi long?
La table sur laquelle je travaille utilise cette table de référence t_ref_ett , tout bêtement , j'ai donc fait un kill car apparemment il y avait une procédure stockée qui ne s'était pas arrété.
J'ai trouvé la table qui me bloque, il s'agit de t_ref_ett , en utilisant la table pg_locks j'obtiens:
relname | mode | granted | pid
-----------------------------------+--------------------------+---------+-------
pk_t_entcdecli | AccessShareLock | t | 6320
pg_class_relname_nsp_index | AccessShareLock | t | 13590
t_ref_ett | AccessExclusiveLock | f | 29689
pk_t_ref_ett | AccessShareLock | t | 6320
pg_locks | AccessShareLock | t | 13590
ak_cle_2_t_entcde | AccessShareLock | t | 6320
pg_class | AccessShareLock | t | 13590
t_ref_ett | AccessShareLock | f | 11354
tmp_entcdecli | AccessShareLock | t | 6320
t_ref_ett | AccessShareLock | t | 6320
ak_cle_unicite_t_ref_et | AccessShareLock | t | 6320
t_ref_ett | AccessExclusiveLock | f | 22781
t_ref_ett | AccessExclusiveLock | f | 9346
t_entcdecli | AccessShareLock | t | 6320
pg_class_oid_index | AccessShareLock | t | 13590
Il ne me reste que 15min donc je vais m'occuper d'autre chose , je verrais sa après le week end.
Je n'ai aucun message d'erreur , au bout de 10min j'ai fais un ctrl - C , pour 1 update je pense que sa fait beaucoup. Oui je l'ai fais , rien d'étrange , je peux faire un delete mais pas de drop , ni utiliser mes fonctions , par contre les autres tables oui.
bizarrement je ne peux même pas non plus supprimer ma table de test et sa table temporaire associé o_O. Sachant que je ne les utilise pas et que je suis le seul à utiliser cette db test.
Oui c'est à peu près sa , en moyenne 25ms pour un insert ; plus rapide pour un update je pense. Mais ma table test contient 100000 lignes , la principale 1M. Je testerai cette méthode plus tard , j'ai quelques problèmes assez contraignant car mes fonctions ne fonctionne plus , du moins je n'ai pas de réponse , même un vacuum full ne se finit pas...
Bon , apparemment c'est impossible. Est-ce que sa ne sera pas mieux et plus rapide d'utiliser des tableaux de taille 1000 comme le bulk collect , de comparer toutes les lignes de ce tableau avec celles de ma table principale et de tout update ou insert d'un coup?
Merci je vais essayer sa , même si sa risque d'être compliqué
En fait le curseur contient toutes les lignes de ma table temporaire , ensuite avec le FETCH je parcours chaque ligne du cursor pour les comparer avec les lignes de ma table principale pour savoir s'il faut faire un update ou un insert , je ne vois pas comment faire cela sans curseur.
Oui mais je ne peux pas faire comme ça. Pour faire de la même façon qu'un bulk collect...limit 1000 est-ce que je pourrais utiliser un curseur avec des tableaux pour mes variables COLUMNS, etc....?
Oui mais ce n'est pas le problème. Le problème c'est qu'il me faut 25min pour insérer 73000 lignes dans une table de 100000 ( c'est une table test qui contient une partie de la table principale qui elle contient des millions de lignes )
l'id est juste une clé primaire créée lorsque l'on insert une ligne de la table temporaire vers la table principale.
En fait l'id de la table est composé de la date + d'un numero de séquence de 8 chiffres donc...Obligé d'utiliser cette méthode , en tout cas c'est exactement la traduction pl/pgSQL du script pl/sql qu'ils ont fait ici , je ne fais que reprendre ce qui est déjà fait.