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

#1 20/09/2019 11:18:11

tbeghain
Membre

differences sqlplus --> psql

Bonjour,

Je constate des différences entre une exécution avec sqlplus sur une base ORACLE et psql sur la même base, mais migrée sous Postgres. Voilà l'ordre SQL

SELECT CHD.CODE_APPLI||','||
       CHD.CH_DOC_TYPE||','||
       CHD.ORIGINATOR
from PCMS_CHDOC_DATA CHD
where CHD.ORIGINATOR = 'TBEGHAIN';

et voilà ce que ça donne avec sqlplus :

ZZ,DM,TBEGHAIN
,EVOLDB,TBEGHAIN
,EVOLDB,TBEGHAIN
MU,URT,TBEGHAIN
,URT,TBEGHAIN
,URT,TBEGHAIN

et avec psql

ZZ,DM,TBEGHAIN


MU,URT,TBEGHAIN

en fait, avec psql, comme la valeur de la première colonne est "null", il n''y a pas affichage du reste des colonnes, à la différence de sqlplus.
Est-ce qu'il y aurait un paramètre à positionner avec psql pour avoir le même comportement qu'avec sqlplus ?
Merci pour vos réponses

Hors ligne

#2 20/09/2019 11:48:17

gleu
Administrateur

Re : differences sqlplus --> psql

Ce n'est pas dû à psql mais à PostgreSQL. Pour Oracle, une chaîne NULL est équivalente à une chaîne vide alors que PostgreSQL fait la différence. Pour PG, concaténer une chaîne inconnue (NULL) avec une chaîne connue donne un résultat inconnu, donc NULL. Il n'y a pas moyen de changer ce comportement (qui respecte la norme SQL pour infos). Donc, si vous voulez le même résultat qu'avec Oracle, il faudra placer vos noms de colonne dans des appels à la fonction coalesce.


Guillaume.

Hors ligne

#3 20/09/2019 12:21:24

tbeghain
Membre

Re : differences sqlplus --> psql

Ah OK. Merci. Effectivement, si je rajoute coalesce, ça marche. Comme je dois migrer vers postgres, ça va m'obliger à revoir pas mal de sql, mais faut ce qu'il faut !

SELECT COALESCE(CHD.CODE_APPLI,' ')||':'||
       CHD.CH_DOC_TYPE||':'||
       CHD.ORIGINATOR
from PCMS_CHDOC_DATA CHD
where CHD.ORIGINATOR = :var1
;

ce qui donne

ZZ:DM:TBEGHAIN
 :EVOLDB:TBEGHAIN
 :EVOLDB:TBEGHAIN
MU:URT:TBEGHAIN
 :URT:TBEGHAIN
 :URT:TBEGHAIN

Hors ligne

#4 20/09/2019 13:45:02

gleu
Administrateur

Re : differences sqlplus --> psql

Attention, cette requête ne fonctionnera comme vous le souhaitez que si CH_DOC_TYPE et/ou ORIGINATOR ne sont pas NULL. Dans le cas contraire, vous aurez de nouveau une valeur NULL. (ceci dit, ces colonnes sont peut-être protégées par une contrainte NOT NULL, auquel cas le problème ne se pose pas)


Guillaume.

Hors ligne

#5 20/09/2019 13:56:51

Marc Cousin
Membre

Re : differences sqlplus --> psql

Sinon si vous migrez d'oracle à pg, avec ora2pg, il me semble qu'il y a le choix entre migrer les chaînes vides d'oracle vers vide ou vers null dans PG. À vérifier


Marc.

Hors ligne

#6 20/09/2019 14:18:41

tbeghain
Membre

Re : differences sqlplus --> psql

Pour Guillaume,
Oui, je le sais. Mais de toute façon, il faut que je modifie et teste tous les scripts systématiquement. Alors je verrai bien là où il faut le coalesce ou pas. Sans compter d'autres problèmes que je vais peut être rencontrer....

Pour Marc,
En fait, nous utilisons un progiciel qui utilise ORACLE comme base de données, et qui offre la possibilité de changer la base de données pour Postgres. Du coup, c'est leur procédure qui s'occupe de migrer les données d'un environnement vers un autre, et je ne sais pas quelle technique ils utilisent. Nous, on a développé des scripts autour, et ce sont ces scripts qu'il me faut modifier.

En tous cas, un grand merci à tous les deux

Thierry

Hors ligne

#7 20/09/2019 15:09:47

dverite
Membre

Re : differences sqlplus --> psql

Tant qu'à réécrire le SQL, voyez si concat() ne serait pas plus lisible. Avec concat() les NULL reviennent au même que les chaines vides au lieu d'avoir l'effet "absorbant" de NULL avec l'opérateur ||:

test=> select concat('abc', ',' , null, ',' , 'def');
  concat  
----------
 abc,,def

concat_ws() peut aussi être utile. C'est encore plus lisible parce qu'on n'a pas besoin de répéter le séparateur mais les NULL sont ignorés.

cf https://www.postgresql.org/docs/current … RING-OTHER

Hors ligne

#8 20/09/2019 15:37:27

tbeghain
Membre

Re : differences sqlplus --> psql

Super, c'est carrément mieux ! On englobe le tout, et pis voila !!

SELECT CONCAT(CHD.CODE_APPLI,':',CHD.CH_DOC_TYPE,':',CHD.ORIGINATOR)
from PCMS_CHDOC_DATA CHD
where CHD.ORIGINATOR = :var1
;
ZZ:DM:TBEGHAIN
:EVOLDB:TBEGHAIN
:EVOLDB:TBEGHAIN
MU:URT:TBEGHAIN
:URT:TBEGHAIN
:URT:TBEGHAIN

Par contre, avec concat_ws, j'obtiens ça, et c'est moins bien car les null ne sont pas pris en compte.
Nous avons souvent des fichiers csv comme résultats de requête qui sont exportés dans Excel.
Dans ma requête exemple, avec concat, j'ai bien tous les séparateurs (:), alors que avec concat_ws, ce n'est pas forcément le cas.

ZZ:DM:TBEGHAIN
EVOLDB:TBEGHAIN
EVOLDB:TBEGHAIN
MU:URT:TBEGHAIN
URT:TBEGHAIN
URT:TBEGHAIN

Merci

Thierry

Hors ligne

Pied de page des forums