Vous n'êtes pas identifié(e).
Pages : 1
merci Guillaume, cela fonctionne très bien.
Bonjour,
je recherche comment interroger le dictionnaire des données afin de récupérer le commentaire d'une vue.
Exemple :
create table test1 (col1 int2);
CREATE OR REPLACE VIEW public.v_test1
AS SELECT test1.col1
FROM test1
WHERE test1.col1 > 20;
COMMENT ON VIEW public.v_test1 IS 'voici ma vue';
Comment faire un select pour récupérer ce commentaire ?
je vous remercie
Fred
bonjour, merci pour ce post.
J'ai testé cela sur PostgreSQL 10.2 et Oracle 12.2:
Au lieu de la commande CREATE FOREIGN TABLE ora_table à effectuer pour chaque table, j'ai testé la commande qui permet de créer toutes les definitions de tables foreign du schéma distant d'un seul coup:
-- <schema oracle> <schema local>
IMPORT FOREIGN SCHEMA "labo" from SERVER oracle_labo INTO schema_labo_local;
Si on a plusieurs schémas distants, on peut créer des schémas postgres distincts, et faire cette commande pour chaque schéma.
Ensuite, on passe de l'un à l'autre avec une commande
set search_path='schema_labo_local';
Pour 1200 définitions de table, la commande s'exécute en 5 à 10 secondes.
J'ai un script sql dans lequel j'effectue une première opération de création de table si elle n'existe pas.
create table if not exists ma_table (col1 int2);
lors de l'exécution, le message suivant apparait :
Fun_clu.sql:19: NOTICE: la relation « ma_table » existe déjà, poursuite du traitement
Est il possible par une commande psql, de masquer le NOTICE, puis re remettre la situation comme avant, parce que dans la suite du script, je souhaite voir les messages NOTICE ?
je vous remercie
Fred
Bonjour, je recherche un algorithme qui me permet de crypter (avec le salt connu de moi) et de decrypter (avec le même salt).
Est il possible de décrypter (l'inverser de la fonction encrypt) ?
merci
merci, cela fonctionne
Bonjour,
je voudrais exécuter une fonction pl/pgsql qui me renvoie un resultat que je voudrais tester dans un shell Unix;
je m'apercois que psql ne sait renvoyer que :
Exit Status
psql returns 0 to the shell if it finished normally, 1 if a fatal error of its own occurs (e.g. out of memory, file not found), 2 if the connection to the server went bad and the session was not interactive, and 3 if an error occurred in a script and the variable ON_ERROR_STOP was set.
Comment faire pour tester dans mon shell le code retour de l'appel d'une fonction pl/pgsql ?
merci pour vos éclairages.
Fred
Bonjour,
Lorsque l'on supprime un enregistrement de la table père, PostgreSQL cherche à savoir s'il existe des enregistrements fils :
select x from table_fille
where id_fk_pere = 'enregistrement père en cours de suppression'
S'il n'y a pas d'index sur id_fk_pere (la colonne de la foreign key), on part pour un sequential scan sur la table fille (mais on ne le voit pas, car cela doit être un ordre généré).
S'il y a un index, on l'utilise.
A moins d'envisager de ne jamais purger d'enregistrements, il me semble que l'on ne peut pas se passer d'index sur les FK.
Test ici avec une table père de 1.509.619 et une table fille de 2.125.573 enregistrements.
-- avec INDEX DE FK :
idev00=> delete from zzjournacl_fred where zzjoidfsys=5003866907;
DELETE 1
Temps : 1,738 ms
-- sans INDEX DE FK :
idev00=> delete from zzjournacl_fred where zzjoidfsys=5003866908;
DELETE 1
Temps : 236,130 ms
Bonjour,
Traditionnellement, j'utilise du TO_CHAR avec un format explicite pour formatter les dates.
Malgré tout, y a t il un moyen de spécifier un format par défaut qui serait DDMMYYYY HH24:MI:SS
afin que la date apparaisse comme cela si aucun formattage n'est effectué ?
j'ai tenté de le faire avec DateStyle (string) mais on est limité dans le format.
Merci de votre aide.
Bonjour,
j'ai essayé de mettre en oeuvre les bloom filters. j'ai suivi le lien : http://blog.coelho.net/database/2016/12 … index.html
j'ai crée une table foo avec 100 millions de lignes
un index bloom, mais quoi que je fasse, je passe toujours en seq scan.
Table « public.foo »
Colonne | Type | Modificateurs
---------+-----------------------------+------------------------------------------------------
id | integer | non NULL Par défaut, nextval('foo_id_seq'::regclass)
c1 | integer |
c2 | integer |
c3 | integer |
c4 | integer |
c5 | integer |
it | timestamp without time zone | non NULL Par défaut, now()
Index :
"foo_c1c2c3c4c5" bloom (c1, c2, c3, c4, c5) WITH (length='64', col1='3', col2='3', col3='3', col4='3', col5='3')
idev00=> explain select * from foo where c1=463274 and c2=459458 and c3=291859 and c4=198159;
QUERY PLAN
---------------------------------------------------------------------------------------
Gather (cost=1000.00..1042428.67 rows=1 width=32)
Workers Planned: 7
-> Parallel Seq Scan on foo (cost=0.00..1041428.57 rows=1 width=32)
Filter: ((c1 = 463274) AND (c2 = 459458) AND (c3 = 291859) AND (c4 = 198159))
(4 lignes)
Quelqu'un aurait une idée ?
merci
je recherche depuis un petit moment le moyen de pouvoir faire l'explain plan d'une requête contenant des variables:
J'ai trouvé ce moyen, si quelqu'un sait faire plus simplement, je suis preneur (notamment sous PGADMIN) :
PREPARE requete2 (integer, char, date)
AS SELECT A.ACOPACOBR1, A.ACOPNUMCIN, A.ACOPCODSIT
FROM ACOPOPER A
WHERE A.ACOPACOBR1 = $1
AND A.ACOPCODSIT = $2
AND A.ACOPDDEOPE <= $3;
PREPARE
EXPLAIN EXECUTE requete2 (544545, '01','2016/01/01');
QUERY PLAN
--------------------------------------------------------------------------------------
Index Scan using acopopercl_pkey on acopopercl (cost=0.43..138.29 rows=47 width=23)
Index Cond: (acopacobr1 = 544545)
Filter: ((acopddeope <= '2016-01-01'::date) AND (acopcodsit = '01'::bpchar))
(3 lignes)
bonjour,
je n'ai pas trouvé le moyen de construire un index en mode parallèle. Même si, en 9.6, j'ai activé les paramètres de parallélisation, ils ne semblent pas pris lors de la création de l'index.
Pour des grosses tables (200 millions de lignes), c'est très long...
1) Est ce que cette fonctionnalité est prévue ?
2) y a t il d'autres paramètres qui peuvent accélerer la création d'un index ?
merci
Quelques tests probants avec la 9.6 beta - il y a 7 workers
select count(*) from PSOSANTECL_X10 (table sans index)
Total query runtime: 3.4 secs
1 ligne récupérée.
105807216 records
Plan d'accès :
explain select count(*) from PSOSANTECL_X10
"Finalize Aggregate (cost=1812523.34..1812523.35 rows=1 width=8)"
" -> Gather (cost=1812522.61..1812523.32 rows=7 width=8)"
" Workers Planned: 7"
" -> Partial Aggregate (cost=1811522.61..1811522.62 rows=1 width=8)"
" -> Parallel Seq Scan on psosantecl_x10 (cost=0.00..1774778.89 rows=14697489 width=0)"
Mais mieux encore :
select PSOSNUMOPE, sum(psosnopart)
from PSOSANTECL_X10
group by PSOSNUMOPE
order by PSOSNUMOPE;
Total query runtime: 7.8 secs
1936 lignes récupérées.
explain select PSOSNUMOPE, sum(psosnopart)
from PSOSANTECL_X10
group by PSOSNUMOPE
order by PSOSNUMOPE;
"Finalize GroupAggregate (cost=1849331.51..1849335.51 rows=64 width=12)"
" Group Key: psosnumope"
" -> Sort (cost=1849331.51..1849332.63 rows=448 width=12)"
" Sort Key: psosnumope"
" -> Gather (cost=1849266.34..1849311.78 rows=448 width=12)"
" Workers Planned: 7"
" -> Partial HashAggregate (cost=1848266.34..1848266.98 rows=64 width=12)"
" Group Key: psosnumope"
" -> Parallel Seq Scan on psosantecl_x10 (cost=0.00..1774778.89 rows=14697489 width=6)"
Paramètres utilisés dans postgres.conf
max_parallel_degree = 16 # max number of worker processes per node
max_worker_processes = 16 # (change requires restart)
Bonjour, je vais peut être enfoncer une porte ouverte, mais bon, on a cherché un peu avant de trouver :
EXEC SQL DECLARE testcsc_csr3 CURSOR FOR SELECT....
EXEC SQL OPEN testcsc_csr3;
EXEC SQL FETCH testcsc_csr3....;
EXEC SQL COMMIT;
EXEC SQL FETCH testcsc_csr3...;
ERROR: cursor "testcsc_csr3" does not exist
La raison est la suivante : le curseur n'a pas été déclaré avec la mention WITH HOLD
voir ici la documentation sur la signification du WITH/WITHOUT HOLD :
http://www.postgresql.org/docs/current/ … clare.html
Fred
Bonjour,
je me permets de faire un post sur la manière d'écrire une fonction qui renvoie plusieurs valeurs dans un record, et la manière de récupérer ces valeurs :
- avec psql,
- avec une fonction PL/pgSQL
- avec un programme C écrit en ecpg.
J'ai un peu galéré pour y arriver (je comprends .... lentement), je me dis que cela pourrait servir à d'autres, alors voici l'exemple.
A exécuter sur psql :
\echo -- ------------------------------
\echo -- creation de la fonction qui renvoie un record
\echo -- contenant 2 parametres :
\echo -- po_number bigint
\echo -- po_coderet bigint
\echo -- ------------------------------
CREATE OR REPLACE FUNCTION zz0001t_seq(
pi_classe text,
pi_nbre bigint DEFAULT 1)
RETURNS record AS
$BODY$
DECLARE
ret RECORD;
po_number bigint;
po_coderet bigint;
BEGIN
-- doing some stuff...
po_number:=23456;
po_coderet:=12;
-- je retourne 2 parametres valorises dans un record (bigint,bigint)
ret := (po_number,po_coderet);
return ret;
END
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100;
\echo -- -----------------------------------------
\echo -- appel de la fonction avec psql pour test
\echo -- -----------------------------------------
select N_NUMBER, TS_CODE_RETOUR
FROM zz0001t_seq('ENIMODIFCL',1)
AS (N_NUMBER bigint, TS_CODE_RETOUR bigint)
\echo -- ------------------------------
\echo -- creation de la fonction qui va appeler une autre fonction PL/pgSQL
\echo -- et afficher les 2 parametres
\echo -- ------------------------------
CREATE OR REPLACE FUNCTION zz0001t_appel ()
RETURNS void
as
$BODY$
DECLARE
WS_IDENT bigint;
WS_CODERET bigint;
ret RECORD;
BEGIN
-- Recuperer identifiant systeme
select N_NUMBER, TS_CODE_RETOUR
FROM zz0001t_seq('ENIMODIFCL',1)
AS (N_NUMBER bigint, TS_CODE_RETOUR bigint)
INTO WS_IDENT, WS_CODERET;
-- Affichage
RAISE INFO 'sequence lue %',WS_IDENT;
RAISE INFO 'Code retour %',WS_CODERET;
END
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100;
\echo -- ------------------------------
\echo -- appel de la fonction
\echo -- ------------------------------
select zz0001t_appel();
L'exécuton sur pgsql donne ceci :
idev05=> \i demo_2_param_out.sql
-- ------------------------------
-- creation de la fonction qui renvoie un record
-- contenant 2 parametres :
-- po_number bigint
-- po_coderet bigint
-- ------------------------------
CREATE FUNCTION
-- -----------------------------------------
-- appel de la fonction avec psql pour test
-- -----------------------------------------
n_number | ts_code_retour
----------+----------------
23456 | 12
(1 ligne)
-- ------------------------------
-- creation de la fonction qui va appeler une autre fonction PL/pgSQL
-- et afficher les 2 parametres
-- ------------------------------
CREATE FUNCTION
-- ------------------------------
-- appel de la fonction
-- ------------------------------
psql:demo_2_param_out.sql:66: INFO: sequence lue 23456
psql:demo_2_param_out.sql:66: INFO: Code retour 12
zz0001t_appel
---------------
(1 ligne)
Pour l'appel en ecpg,l'écriture est la suivante :
EXEC SQL SELECT a, b INTO :N_NUMBER,:TS_CODE_RETOUR
FROM zz0001t_seq(:N_CLASS,:N_INCREMENT)
AS (a bigint, b bigint);
voila, j'espère que je n'ai pas dit trop de bêtises, si vous avez plus simple, je suis preneur.
Fred
Bonjour Guillaume,
Effectivement, avec les savepoint, on s'en sort. Voici un exemple et le résultat sur psql
\set AUTOCOMMIT off
-- debut DDL
drop table fred;
create table fred (
cle integer not null,
libelle varchar(30) not null);
alter table fred add constraint fred_pk primary key (cle);
commit;
-- fin DDL
-- debut DML
begin transaction;
insert into fred (cle, libelle ) values (10,'frederic');
insert into fred (cle, libelle ) values (20,'frederic');
-- on genere un plantage, pour continuer, il faut faire rollback;
savepoint CLE_DUPLIQUEE;
insert into fred (cle, libelle) values (10,'frederic');
rollback to savepoint CLE_DUPLIQUEE;
update fred set libelle='fred' where cle=10;
commit;
select * from fred order by 1;
DROP TABLE
CREATE TABLE
ALTER TABLE
COMMIT
BEGIN
INSERT 0 1
INSERT 0 1
SAVEPOINT
psql:test_transaction2.sql:23: ERREUR: la valeur d'une clé dupliquée rompt la contrainte unique « fred_pk »
DÉTAIL : La clé « (cle)=(10) » existe déjà.
ROLLBACK
UPDATE 1
COMMIT
cle | libelle
-----+----------
10 | fred
20 | frederic
(2 lignes)
Bon, je me suis mal exprimé.
Soit une transaction faisant plusieurs ordres SQL en ecpg.
le 15eme ordre SQL fait un insert qui renvoie une erreur de type viloation de contrainte.
Comment faire en sorte de pouvoir gérer applicativement cette erreur et poursuivre la transaction jusqu'à un commit ?
sqlcode: -400
sqlerrm.sqlerrml: 124
sqlerrm.sqlerrmc: une instruction insert ou update sur la table « acelcothcl » viole la contrainte de clé
étrangère « acelacegfk » on line 276
Exemple : voici ce que je souhaite faire : si j'ai l'erreur ci-dessus, alors, je fais update puis je termine ma transaction.
Ce que je comprends actuellement, c'est que le 15eme ordre SQL qui part au tapis fiche en l'air toute la transaction, et qu'il n'y a plus qu'à faire un rollback(ou commit) pour pouvoir continuer.
a la différence d'autres sgbd, où l'on peut gérer chaque code errreur sans qu'un rollback général se produise.
Autrement dit, une transaction doit être un "sans faute" sinon, il n'y a plus qu'à recommencer depuis le début.
j'ai tenté de gérer cela avec les WHENEVER
j'espère que ce sera plus clair, et que vous pourrez m'aider.
Merci
Fred
Bonjour.
j'ai un programme ecpg que je suis en train de porter sur PG.
son comportement initial est le suivant : il essaie d'insérer, et si l'enregistrement existe déjà, il fait un update.
begin transaction
exec sql insert into TABLE1 (CLE_PK, VALEUR) values ('A','fred');
# si le code erreur retourné vaut "duplicate key" alors je fais un update
if (sqlcode= 'dupkey' ) then
EXEC SQL UPDATE TABLE1 SET VALEUR='fred' WHERE CLE_PK='A';
end if;
EXEC SQL COMMIT;
Dans la pratique, je comprends que la première instruction qui renvoie un code erreur différent de zéro rollbacke toute la transaction.
je me vois mal devoir faire des select avant les insert afin d'éviter de tomber sur des erreurs.
y a t il un moyen de gérer les codes erreurs, sans "casser" la transaction embedded C ?
je vous remercie
Fred
Pages : 1