{"id":6608,"date":"2026-04-14T23:06:24","date_gmt":"2026-04-14T21:06:24","guid":{"rendered":"https:\/\/rootfan.com\/?p=6608"},"modified":"2026-04-14T23:06:27","modified_gmt":"2026-04-14T21:06:27","slug":"mapping-de-types-de-donnees-oracle-vers-postgresql","status":"publish","type":"post","link":"https:\/\/rootfan.com\/fr\/oracle-to-postgresql-data-type-mapping\/","title":{"rendered":"Le guide complet de la correspondance des types de donn\u00e9es Oracle vers PostgreSQL"},"content":{"rendered":"<p><strong>TL;DR :<\/strong> La plupart des correspondances de types de donn\u00e9es Oracle vers PostgreSQL sont simples.<br>Les dangereux ne le sont pas.<br>La date Oracle inclut une composante temporelle que la date PostgreSQL \u00e9limine silencieusement.<br>Oracle NUMBER est mapp\u00e9 \u00e0 NUMERIC par d\u00e9faut, ce qui est correct mais lent pour les charges de travail enti\u00e8res.<br>Les cha\u00eenes vides dans Oracle sont NULL ; dans PostgreSQL, elles ne le sont pas.<br>Ce guide vous donne la table de correspondance compl\u00e8te et couvre les cinq pi\u00e8ges qui entra\u00eenent une corruption silencieuse des donn\u00e9es lors de la migration.<\/p>\n\n\n\n<!--more-->\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<p>Le probl\u00e8me de donn\u00e9es le plus courant dans un exercice de mappage de types de donn\u00e9es d'Oracle \u00e0 PostgreSQL n'est pas une colonne manquante ou un \u00e9chec d'importation.<\/p>\n\n\n\n<p>C'est une correspondance qui semble correcte, passe la validation et modifie vos donn\u00e9es en silence.<\/p>\n\n\n\n<p>Les projets de migration o\u00f9 les dates ont perdu leur composante temporelle, o\u00f9 le calcul entier est devenu extr\u00eamement lent et o\u00f9 la logique applicative a \u00e9t\u00e9 compromise parce que les cha\u00eenes vides ont cess\u00e9 de se comporter comme NULL \u2014 aucun de ces probl\u00e8mes n'\u00e9tait \u00e9vident au stade de la conversion du sch\u00e9ma.<\/p>\n\n\n\n<p>Elles \u00e9taient toutes \u00e9vitables.<\/p>\n\n\n\n<p>Ce guide vous donne la table de correspondance compl\u00e8te et explique les d\u00e9cisions qui comptent.<\/p>\n\n\n\n<p>Si vous \u00eates au d\u00e9but de votre <a href=\"\/fr\/pourquoi-les-entreprises-quittent-elles-oracle-pour-postgresql\/\">Migration d'Oracle vers PostgreSQL<\/a>, enregistrez cette page.<\/p>\n\n\n\n<p>Tu y reviendras.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<div class=\"wp-block-rank-math-toc-block\" id=\"rank-math-toc\"><h2>Table des mati\u00e8res<\/h2><nav><ul><li><a href=\"#the-complete-oracle-to-postgre-sql-data-type-mapping-table\">Tableau complet de mappage des types de donn\u00e9es Oracle vers PostgreSQL<\/a><\/li><li><a href=\"#why-does-oracle-date-break-everything-in-postgre-sql\">Pourquoi le type de donn\u00e9es DATE d'Oracle pose-t-il probl\u00e8me dans PostgreSQL ?<\/a><\/li><li><a href=\"#how-should-you-map-oracle-number-for-performance\">Comment mapper un Oracle NUMBER pour de meilleures performances ?<\/a><\/li><li><a href=\"#what-happens-to-oracle-clob-and-blob\">Qu'advient-il des CLOB et BLOB d'Oracle ?<\/a><\/li><li><a href=\"#five-type-traps-that-catch-teams-off-guard\">Cinq pi\u00e8ges de type qui surprennent les \u00e9quipes<\/a><\/li><li><a href=\"#what-does-ora-2-pg-handle-automatically\">Qu'est-ce qu'ora2pg g\u00e8re automatiquement ?<\/a><\/li><li><a href=\"#the-data-type-decision-checklist\">La liste de contr\u00f4le de d\u00e9cision des types de donn\u00e9es<\/a><\/li><li><a href=\"#frequently-asked-questions\">Foire aux questions<\/a><ul><li><a href=\"#faq-question-1775170973711\">Ora2pg g\u00e8re-t-il automatiquement toutes les conversions de types de donn\u00e9es Oracle ?<\/a><\/li><li><a href=\"#faq-question-1775170974711\">La date PostgreSQL \u00e9quivalente \u00e0 Oracle DATE est TIMESTAMP.<\/a><\/li><li><a href=\"#faq-question-1775170975711\">Comment convertir efficacement les colonnes Oracle NUMBER en PostgreSQL ?<\/a><\/li><li><a href=\"#faq-question-1775170976711\">Que devient le BOOLEAN d'Oracle dans PostgreSQL ?<\/a><\/li><li><a href=\"#faq-question-1775170977711\">PostgreSQL peut-il g\u00e9rer les donn\u00e9es CLOB d'Oracle ?<\/a><\/li><\/ul><\/li><li><a href=\"#in-summary\">En r\u00e9sum\u00e9<\/a><\/li><\/ul><\/nav><\/div>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"the-complete-oracle-to-postgre-sql-data-type-mapping-table\">Tableau complet de mappage des types de donn\u00e9es Oracle vers PostgreSQL<\/h2>\n\n\n\n<p>Le tableau ci-dessous couvre tous les types Oracle courants.<\/p>\n\n\n\n<p>La colonne \u201c Safe Default \u201d est ce qu'ora2pg utilise automatiquement.<\/p>\n\n\n\n<p>La colonne \u201c Recommand\u00e9 \u201d est celle que vous devriez r\u00e9ellement utiliser apr\u00e8s avoir analys\u00e9 vos donn\u00e9es.<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table><thead><tr><th>Type Oracle<\/th><th>S\u00fbr par d\u00e9faut<\/th><th>Recommand\u00e9<\/th><th>Notes<\/th><\/tr><\/thead><tbody><tr><td>NOMBRE<\/td><td>NUM\u00c9RIQUE<\/td><td>ENTIER, GRAND ENTIER, ou NUM\u00c9RIQUE<\/td><td>D\u00e9pend de l'\u00e9chelle et de la port\u00e9e \u2014 voir la section ci-dessous<\/td><\/tr><tr><td>NUMBER(p, 0)<\/td><td>NUM\u00c9RIC(p)<\/td><td>SMALLINT \/ INTEGER \/ BIGINT<\/td><td>Utilisez des types entiers pour de meilleures performances<\/td><\/tr><tr><td>NOMBRE(p, s)<\/td><td>NUMERIC(p, s)<\/td><td>NUMERIC(p, s)<\/td><td>Correspondance exacte<\/td><\/tr><tr><td>VARCHAR2(n)<\/td><td>VARCHAR(n)<\/td><td>VARCHAR(n) ou TEXTE<\/td><td>n est le nombre de caract\u00e8res dans PG ; peut n\u00e9cessiter un ajustement pour les colonnes s\u00e9mantiques en octets<\/td><\/tr><tr><td>NVARCHAR2(n)<\/td><td>VARCHAR(n)<\/td><td>VARCHAR(n)<\/td><td>PG est toujours UTF-8 ; aucun type unicode s\u00e9par\u00e9 n'est n\u00e9cessaire<\/td><\/tr><tr><td>CAR(n)<\/td><td>CAR(n)<\/td><td>CAR(n)<\/td><td>Correspondance directe<\/td><\/tr><tr><td>DATE<\/td><td>HORODATEUR<\/td><td>HORODATEUR<\/td><td>Oracle DATE inclut l'heure \u2014 ne jamais mapper sur PG DATE<\/td><\/tr><tr><td>HORODATEUR<\/td><td>HORODATEUR<\/td><td>HORODATEUR<\/td><td>Correspondance directe<\/td><\/tr><tr><td>HORODATE AVEC D\u00c9CALAGE HORAIRE<\/td><td>TIMESTAMPTZ<\/td><td>TIMESTAMPTZ<\/td><td>Les s\u00e9mantiques de stockage diff\u00e8rent \u2014 voir la section ci-dessous<\/td><\/tr><tr><td>HORODATAGE AVEC FUSEAU HORAIRE LOCAL<\/td><td>TIMESTAMPTZ<\/td><td>TIMESTAMPTZ<\/td><td>M\u00eame mise en garde<\/td><\/tr><tr><td>INTERVALLE ANCIENNE \u00c0 MOIS<\/td><td>INTERVALLE<\/td><td>INTERVALLE<\/td><td>BG INTERVAL est un type flexible unique<\/td><\/tr><tr><td>INTERVALLE JOUR AU SECONDE<\/td><td>INTERVALLE<\/td><td>INTERVALLE<\/td><td>Tester l'arithm\u00e9tique des dates aux limites mois\/jour<\/td><\/tr><tr><td>CLOB<\/td><td>Texte<\/td><td>Texte<\/td><td>PG TEXT illimit\u00e9 en pratique (jusqu'\u00e0 ~1 Go via TOAST)<\/td><\/tr><tr><td>NCLOB<\/td><td>Texte<\/td><td>Texte<\/td><td>Idem<\/td><\/tr><tr><td>BLOB<\/td><td>BYTEA<\/td><td>BYTEA ou LOB<\/td><td>lo pour les gros fichiers ou les cas d'utilisation de streaming<\/td><\/tr><tr><td>BRUT(n)<\/td><td>BYTEA<\/td><td>BYTEA<\/td><td>Remplacement direct<\/td><\/tr><tr><td>LONG BRUT<\/td><td>BYTEA<\/td><td>BYTEA<\/td><td>Obsol\u00e8te dans Oracle ; migrez rapidement<\/td><\/tr><tr><td>LONGUE<\/td><td>Texte<\/td><td>Texte<\/td><td>Obsol\u00e8te dans Oracle<\/td><\/tr><tr><td>XMLTYPE<\/td><td>XML<\/td><td>XML<\/td><td>La requ\u00eate PG XML utilise XPATH() et XMLTABLE()<\/td><\/tr><tr><td>FLOTTANT_BINAIRE<\/td><td>R\u00c9EL<\/td><td>R\u00c9EL<\/td><td>Nombre flottant IEEE 754 4 octets \u2013 correspondance directe<\/td><\/tr><tr><td>BINAIRE_DOUBLE<\/td><td>DOUBLE PR\u00c9CISION<\/td><td>DOUBLE PR\u00c9CISION<\/td><td>8-octet IEEE 754 \u2014 correspondance directe<\/td><\/tr><tr><td>BOOLEAN (Oracle 23c+)<\/td><td>BOUL\u00c9EN<\/td><td>BOUL\u00c9EN<\/td><td>Pre-23c : NUMBER(1) ou CHAR(1) \u2014 conversion manuelle requise<\/td><\/tr><tr><td>ROWID \/ UROWID<\/td><td>Aucun \u00e9quivalent<\/td><td>Refonte avec cl\u00e9 primaire<\/td><td>Le ctid de PG n'est pas stable apr\u00e8s un VACUUM ou un clustering.<\/td><\/tr><tr><td>SDO_GEOMETRY<\/td><td>Pas int\u00e9gr\u00e9<\/td><td>PostGIS GEOMETRY<\/td><td>N\u00e9cessite l'extension PostGIS<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"why-does-oracle-date-break-everything-in-postgre-sql\">Pourquoi le type de donn\u00e9es DATE d'Oracle pose-t-il probl\u00e8me dans PostgreSQL ?<\/h2>\n\n\n\n<p>Oracle DATE stocke la date et l'heure. PostgreSQL DATE stocke uniquement la date.<br>Le mappage d'Oracle DATE vers PostgreSQL DATE ignore silencieusement le composant temporel de chaque valeur de cette colonne \u2014 aucune erreur, aucun avertissement, les d\u00e9comptes de lignes correspondent toujours.<br>Toujours mapper Oracle DATE \u00e0 PostgreSQL TIMESTAMP.<\/p>\n\n\n\n<p>C'est la corruption silencieuse de donn\u00e9es la plus courante lors des migrations d'Oracle vers PostgreSQL.<\/p>\n\n\n\n<p>L'importation r\u00e9ussit.<\/p>\n\n\n\n<p>Les comptes de lignes correspondent.<\/p>\n\n\n\n<p>Les donn\u00e9es sont erron\u00e9es.<\/p>\n\n\n\n<p>Le mappage correct est toujours Oracle DATE vers PostgreSQL TIMESTAMP.<\/p>\n\n\n\n<p><a href=\"https:\/\/docs.aws.amazon.com\/dms\/latest\/oracle-to-aurora-postgresql-migration-playbook\/chap-oracle-aurora-pg.tables.common.html\" rel=\"nofollow noopener\" target=\"_blank\">Selon le guide de migration d'AWS, Oracle vers Aurora PostgreSQL<\/a>, ceci est un mappage obligatoire, pas facultatif.<\/p>\n\n\n\n<p>ora2pg g\u00e8re cela correctement par d\u00e9faut.<\/p>\n\n\n\n<p>Deux probl\u00e8mes de suivi \u00e0 v\u00e9rifier apr\u00e8s le remappage :<\/p>\n\n\n\n<p><strong>TRUNC(date) en SQL et PL\/SQL.<\/strong><br>Les d\u00e9veloppeurs Oracle utilisent fr\u00e9quemment <code>TRUNC(SYSDATE)<\/code> pour supprimer la composante temporelle et obtenir minuit.<br>Sous PostgreSQL, l'\u00e9quivalent est <code>DATE_TRUNC('day', now())<\/code>.<br>Toutes les requ\u00eates ou proc\u00e9dures stock\u00e9es utilisant TRUNC d'Oracle sur une colonne de date doivent \u00eatre mises \u00e0 jour.<\/p>\n\n\n\n<p><strong>Comparaisons de dates au niveau applicatif.<\/strong><br>Code qui compare des dates avec <code>= TRUNC(SYSDATE)<\/code> (v\u00e9rification des enregistrements d\u2019aujourd\u2019hui) se comporte diff\u00e9remment une fois que la colonne est TIMESTAMP.<br>V\u00e9rifiez toute la logique de comparaison de dates dans le code de l'application, pas seulement dans la base de donn\u00e9es.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"how-should-you-map-oracle-number-for-performance\">Comment mapper un Oracle NUMBER pour de meilleures performances ?<\/h2>\n\n\n\n<p>N'acceptez jamais NUMERIC pour toutes les colonnes NUMBER.<br>NUMERIC utilise l'arithm\u00e9tique \u00e0 pr\u00e9cision arbitraire \u2014 correcte mais lente pour les charges de travail enti\u00e8res.<br>Analysez la plage et l'\u00e9chelle r\u00e9elles de chaque colonne : utilisez INTEGER pour les valeurs jusqu'\u00e0 2,1 milliards, BIGINT pour la plage 64 bits, NUMERIC(p,s) pour une pr\u00e9cision d\u00e9cimale fixe.<br>Modifier les valeurs par d\u00e9faut d'ora2pg avec la directive MODIFY_TYPE.<\/p>\n\n\n\n<p>La bonne approche est d'abord d'analyser vos donn\u00e9es r\u00e9elles :<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>NUMBER(p, 0)<\/strong> o\u00f9 les valeurs rentrent dans 32 bits : utilisez INTEGER (jusqu'\u00e0 2,1 milliards)<\/li>\n\n\n\n<li><strong>NUMBER(p, 0)<\/strong> o\u00f9 les valeurs s'inscrivent dans 64 bits : utilisez BIGINT (jusqu'\u00e0 9,2 \u00d7 10\u00b9\u2078)<\/li>\n\n\n\n<li><strong>NOMBRE(p, s)<\/strong> avec une pr\u00e9cision d\u00e9cimale fixe : utilisez NUMERIC(p, s)<\/li>\n\n\n\n<li><strong>NOMBRE<\/strong> sans pr\u00e9cision (calculs flottants) : consid\u00e9rez DOUBLE PRECISION pour la vitesse, NUMERIC pour l'exactitude<\/li>\n<\/ul>\n\n\n\n<p><a href=\"https:\/\/aws.amazon.com\/blogs\/database\/convert-the-number-data-type-from-oracle-to-postgresql-part-1\/\" rel=\"nofollow noopener\" target=\"_blank\">AWS a publi\u00e9 une analyse en deux parties<\/a> sur la fa\u00e7on d'\u00e9valuer les colonnes Oracle NUMBER et d'attribuer le bon type PostgreSQL.<\/p>\n\n\n\n<p>Le processus consiste \u00e0 interroger Oracle pour trouver la distribution r\u00e9elle des minimum, maximum et de l'\u00e9chelle pour chaque colonne avant de prendre une d\u00e9cision.<\/p>\n\n\n\n<p>Dans ora2pg, vous remplacez la valeur par d\u00e9faut par le <code>MODIFICATION_TYPE<\/code> directive dans votre fichier de configuration :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>MODIFY_TYPE COMMANDES.MONTANT_TOTAL:num\u00e9rique(15,2),COMMANDES.CODE_STATUT:entier<\/code><\/pre>\n\n\n\n<p>Ceci est au niveau de la colonne.<\/p>\n\n\n\n<p>Vous le d\u00e9finissez par table apr\u00e8s avoir analys\u00e9 le profil des donn\u00e9es r\u00e9elles de chaque colonne.<\/p>\n\n\n\n<p>Sauter cette \u00e9tape et accepter NUMERIC partout est l'une des causes les plus courantes de mauvaises performances de PostgreSQL imm\u00e9diatement apr\u00e8s une migration.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"what-happens-to-oracle-clob-and-blob\">Qu'advient-il des CLOB et BLOB d'Oracle ?<\/h2>\n\n\n\n<p>Oracle CLOB est mapp\u00e9 \u00e0 PostgreSQL TEXT, qui g\u00e8re des valeurs allant jusqu'\u00e0 environ 1 Go via le stockage TOAST \u2014 aucune modification de l'application n'est n\u00e9cessaire pour les donn\u00e9es elles-m\u00eames.<\/p>\n\n\n\n<p>Les BLOB Oracle correspondent \u00e0 BYTEA pour la plupart des cas d'utilisation, ou au type lo pour le streaming.<\/p>\n\n\n\n<p>Les travaux de migration r\u00e9\u00e9crivent les appels au package DBMS_LOB ; il n'y a pas d'\u00e9quivalent PostgreSQL.<\/p>\n\n\n\n<p>L'exception concerne le code d'application qui utilise le package DBMS_LOB d'Oracle : DBMS_LOB.READ, DBMS_LOB.WRITE, DBMS_LOB.GETLENGTH, et ainsi de suite.<\/p>\n\n\n\n<p>Ce sont des API LOB sp\u00e9cifiques \u00e0 Oracle.<\/p>\n\n\n\n<p>Ils doivent \u00eatre r\u00e9\u00e9crits pour utiliser les fonctions de cha\u00eene SQL standard dans PostgreSQL.<\/p>\n\n\n\n<p>Il n'y a pas d'\u00e9quivalent \u00e0 DBMS_LOB dans PostgreSQL.<\/p>\n\n\n\n<p>BLOB est plus nuanc\u00e9.<\/p>\n\n\n\n<p>PostgreSQL a deux options :<\/p>\n\n\n\n<p><strong>BYTEA<\/strong> stocke les donn\u00e9es binaires en ligne dans la ligne, jusqu'\u00e0 environ 1 Go.<br>C'est plus simple et fonctionne bien pour les images, les documents et le contenu binaire de petite \u00e0 moyenne taille.<\/p>\n\n\n\n<p><strong>Grands Objets (type lo)<\/strong> stocker des donn\u00e9es dans le catalogue syst\u00e8me pg_largeobject et prendre en charge l'acc\u00e8s en flux via lo_read et lo_write.<br>Ceci est plus proche de la s\u00e9mantique des BLOB Oracle pour les applications qui diffusent du contenu binaire par morceaux.<br>Les gros objets n\u00e9cessitent une gestion explicite de leur cycle de vie : vous devez appeler lo_unlink() pour les supprimer, ou utiliser l'extension lo pour g\u00e9rer cela automatiquement via des d\u00e9clencheurs.<\/p>\n\n\n\n<p>Pour la plupart des migrations, BYTEA est le bon choix, sauf si vous avez une exigence de streaming sp\u00e9cifique.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"five-type-traps-that-catch-teams-off-guard\">Cinq pi\u00e8ges de type qui surprennent les \u00e9quipes<\/h2>\n\n\n\n<p>Ceux-ci n'apparaissent pas toujours dans les rapports automatis\u00e9s de conversion de sch\u00e9ma.<\/p>\n\n\n\n<p>Ils cassent des choses \u00e0 l'ex\u00e9cution, souvent dans des cas limites qui ne sont pas couverts par les tests de base.<\/p>\n\n\n\n<p><strong>1. Une cha\u00eene vide est \u00e9gale \u00e0 NULL dans Oracle.<\/strong><br>Oracle VARCHAR2 traite une cha\u00eene vide (<code>'' <\/code>) comme NULL.<br>PostgreSQL les traite comme des valeurs diff\u00e9rentes.<br>Toute logique d'application ou SQL qui repose sur <code>colonne EST NUL<\/code> pour attraper \u00e0 la fois NULL et des cha\u00eenes vides cela \u00e9chouera silencieusement.<br>Toute contrainte NOT NULL sur une colonne VARCHAR2 dans Oracle n'emp\u00eache pas les cha\u00eenes vides.<br>Dans PostgreSQL, il emp\u00eache les cha\u00eenes vides.<br>Auditer chaque contrainte NOT NULL et chaque <code>EST NUL<\/code> \/ <code>N'EST PAS NUL<\/code> V\u00e9rifiez dans votre base de code avant la bascule.<\/p>\n\n\n\n<p><strong>2. VARCHAR2 s\u00e9mantique par octet vs par caract\u00e8re.<\/strong><br><code>VARCHAR2(20 octets)<\/code> et <code>VARCHAR2(20 caract\u00e8res)<\/code> sont diff\u00e9rents dans Oracle.<br>PostgreSQL VARCHAR(n) signifie toujours des caract\u00e8res.<br>Une colonne d\u00e9finie comme VARCHAR2(20 OCTETS) dans une base de donn\u00e9es Oracle \u00e0 caract\u00e8re unique peut contenir jusqu'\u00e0 20 caract\u00e8res.<br>La m\u00eame colonne migr\u00e9e avec le codage AL32UTF8 pourrait contenir moins de caract\u00e8res si des caract\u00e8res multibytes sont pr\u00e9sents.<br>Lors de la migration de bases de donn\u00e9es Oracle utilisant WE8MSWIN1252 ou des jeux de caract\u00e8res \u00e0 octet unique similaires, v\u00e9rifiez explicitement les longueurs de colonnes apr\u00e8s la conversion.<\/p>\n\n\n\n<p><strong>3. BOOLEAN avant Oracle 23c.<\/strong><br>Oracle n'avait pas de type BOOLEAN natif en SQL avant la version 23c (sortie en 2023).<br>Les solutions de contournement courantes \u00e9taient NUMBER(1) avec une contrainte de v\u00e9rification (0 pour faux, 1 pour vrai) ou CHAR(1) (\u2018Y\u2019\/\u2018N\u2019).<br>Ni l'un ni l'autre n'est automatiquement d\u00e9tect\u00e9 comme candidat bool\u00e9en par ora2pg.<br>Vous devez identifier manuellement ces colonnes et configurer <code>MODIFICATION_TYPE<\/code> pour les mapper au type BOOLEAN de PostgreSQL, ainsi que pour mettre \u00e0 jour toute logique applicative qui ins\u00e8re des valeurs 0\/1 ou \u2018Y\u2019\/\u2018N\u2019.<\/p>\n\n\n\n<p><strong>4. ROWID et UROWID.<\/strong><br>Les applications Oracle utilisent parfois le ROWID pour r\u00e9cup\u00e9rer rapidement des lignes : stockez le ROWID d'une ligne, puis utilisez-le pour r\u00e9cup\u00e9rer rapidement cette ligne plus tard.<br>L'identifiant physique de ligne de PostgreSQL (ctid) n'est pas stable.<br>Il change lorsqu'une ligne est mise \u00e0 jour, lorsqu'un VACUUM FULL est ex\u00e9cut\u00e9, ou lorsqu'une table est group\u00e9e.<br>Toute logique d'application qui stocke et r\u00e9utilise des ROWIDs doit \u00eatre repens\u00e9e avec une cl\u00e9 primaire appropri\u00e9e.<\/p>\n\n\n\n<p><strong>5. S\u00e9mantique de stockage de TIMESTAMP WITH TIME ZONE.<\/strong><br>Oracle TIMESTAMP WITH TIME ZONE stocke le d\u00e9calage d'origine (par exemple, <code>2024-03-15 14:30:00 +02:00<\/code>).<br>TIMESTAMPTZ de PostgreSQL est toujours converti en UTC en interne et applique le fuseau horaire de la session lors de l'affichage.<br>La valeur semble identique en sortie, mais la repr\u00e9sentation interne diff\u00e8re.<br>Ceci est important lorsque votre application lit directement les d\u00e9calages de fuseau horaire de la base de donn\u00e9es, ou lorsque vous comparez des valeurs entre des sessions avec des param\u00e8tres de fuseau horaire diff\u00e9rents.<br>Testez explicitement les requ\u00eates sensibles au fuseau horaire.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p><strong>Vous n'\u00eates pas s\u00fbr de celles de ces pi\u00e8ges qui s'appliquent \u00e0 votre sch\u00e9ma ?<\/strong><br>Je propose une \u00e9valuation de migration \u00e0 prix fixe qui examine vos types de donn\u00e9es, le volume de PL\/SQL et les d\u00e9pendances SQL de l'application \u2014 et livre un registre des risques \u00e9crit avant le d\u00e9but de tout travail de migration.<br><a href=\"https:\/\/rootfan.com\/fr\/services\/\">Voir ce que couvre l'\u00e9valuation<\/a><\/p>\n<\/blockquote>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"what-does-ora-2-pg-handle-automatically\">Qu'est-ce qu'ora2pg g\u00e8re automatiquement ?<\/h2>\n\n\n\n<p>ora2pg mappe correctement DATE \u00e0 TIMESTAMP, CLOB et NCLOB \u00e0 TEXT, BLOB et RAW \u00e0 BYTEA, BINARY_FLOAT \u00e0 REAL, BINARY_DOUBLE \u00e0 DOUBLE PRECISION, et XMLTYPE \u00e0 XML.<br>Ce qu'il ne prend pas en charge : optimisation des nombres vers des types entiers, d\u00e9tection de colonnes bool\u00e9ennes, diff\u00e9rences d'encodage VARCHAR2 et r\u00e9\u00e9critures de DBMS_LOB.<br>Ceux-ci n\u00e9cessitent une configuration manuelle de MODIFY_TYPE.<\/p>\n\n\n\n<p>Ce qu'ora2pg ne g\u00e8re pas automatiquement :<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>nombre en types entiers.<\/strong> Toutes les colonnes de type NOMBRE sont par d\u00e9faut de type NUM\u00c9RIQUE. Vous devez utiliser le <code>MODIFICATION_TYPE<\/code> directive de substituer au niveau de la colonne.<\/li>\n\n\n\n<li><strong>D\u00e9tection bool\u00e9enne.<\/strong> Les colonnes NUMBER(1) et CHAR(1) utilis\u00e9es comme bool\u00e9ens ne sont pas d\u00e9tect\u00e9es automatiquement. Une configuration manuelle est requise.<\/li>\n\n\n\n<li><strong>S\u00e9mantique des octets par rapport \u00e0 la s\u00e9mantique des caract\u00e8res VARCHAR2.<\/strong> ora2pg n'ajuste pas la longueur des colonnes pour les diff\u00e9rences d'encodage. Une r\u00e9vision manuelle est n\u00e9cessaire pour les bases de donn\u00e9es sources non UTF8.<\/li>\n\n\n\n<li><strong>Colonnes ROWID.<\/strong> ora2pg signale ces \u00e9l\u00e9ments mais ne les remplace pas. Une refonte manuelle est n\u00e9cessaire.<\/li>\n\n\n\n<li><strong>Appels DBMS_LOB en PL\/SQL.<\/strong> ora2pg convertit la structure PL\/SQL mais ne r\u00e9\u00e9crit pas les appels aux API LOB. Ceux-ci n\u00e9cessitent un remplacement manuel.<\/li>\n<\/ul>\n\n\n\n<p>Le <a href=\"https:\/\/ora2pg.darold.net\/documentation.html\" rel=\"nofollow noopener\" target=\"_blank\">documentation officielle ora2pg<\/a> couvre la r\u00e9f\u00e9rence compl\u00e8te de configuration.<\/p>\n\n\n\n<p>Le <code>TYPE_DE_DONN\u00c9ES<\/code> la directive permet le remappage de types global.<\/p>\n\n\n\n<p><code>MODIFICATION_TYPE<\/code> permet des remplacements au niveau des colonnes.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"the-data-type-decision-checklist\">La liste de contr\u00f4le de d\u00e9cision des types de donn\u00e9es<\/h2>\n\n\n\n<p>Avant d'ex\u00e9cuter votre conversion de sch\u00e9ma, parcourez cette liste :<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Identifier toutes les colonnes de type Oracle DATE et confirmer leur mappage en TIMESTAMP<\/li>\n\n\n\n<li>Interroger chaque colonne NUM\u00c9RIQUE pour d\u00e9terminer la plage et l'\u00e9chelle r\u00e9elles<\/li>\n\n\n\n<li>D\u00e9finir les remplacements MODIFY_TYPE pour les colonnes NUMBER(p,0) de type entier.<\/li>\n\n\n\n<li>Identifier les colonnes bool\u00e9ennes NUMBER(1) et CHAR(1) et configurer MODIFY_TYPE<\/li>\n\n\n\n<li>V\u00e9rifier le jeu de caract\u00e8res source Oracle pour la s\u00e9mantique octet ou caract\u00e8re VARCHAR2<\/li>\n\n\n\n<li>Auditer tout <code>EST NUL<\/code> v\u00e9rifier dans le code de l'application la gestion des cha\u00eenes vides<\/li>\n\n\n\n<li>Lister toutes les utilisations de ROWID dans le code de l'application et concevoir des remplacements de cl\u00e9s primaires<\/li>\n\n\n\n<li>Identifier les appels DBMS_LOB en PL\/SQL et planifier des r\u00e9\u00e9critures<\/li>\n\n\n\n<li>Testez les requ\u00eates TIMESTAMP WITH TIME ZONE avec diff\u00e9rents param\u00e8tres de fuseau horaire de session<\/li>\n<\/ul>\n\n\n\n<p>Obtenir la correspondance des types correctement avant de commencer permet d'\u00e9viter des reprises de travail importantes apr\u00e8s la migration des donn\u00e9es.<\/p>\n\n\n\n<p><a href=\"https:\/\/rootfan.com\/fr\/services\/\">Une \u00e9valuation de migration<\/a> attrape la plupart de ceux-ci avant le d\u00e9but du projet.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"frequently-asked-questions\">Foire aux questions<\/h2>\n\n\n<div id=\"rank-math-faq\" class=\"rank-math-block\">\n<div class=\"rank-math-list\">\n<div id=\"faq-question-1775170973711\" class=\"rank-math-list-item\">\n<h3 class=\"rank-math-question\"><strong>Ora2pg g\u00e8re-t-il automatiquement toutes les conversions de types de donn\u00e9es Oracle ?<\/strong><\/h3>\n<div class=\"rank-math-answer\">\n\n<p>ora2pg g\u00e8re la plupart des conversions courantes correctement, y compris DATE vers TIMESTAMP, CLOB vers TEXT et BLOB vers BYTEA.<br \/>Il n'optimise pas automatiquement NUMBER en types entiers, ne d\u00e9tecte pas les colonnes bool\u00e9ennes \u00e0 partir des solutions de contournement NUMBER(1) ou CHAR(1), ni n'ajuste les longueurs VARCHAR2 pour la s\u00e9mantique octet par caract\u00e8re.<br \/>Ceux-ci n\u00e9cessitent une configuration manuelle \u00e0 l'aide de la directive MODIFY_TYPE dans ora2pg.conf.<\/p>\n\n<\/div>\n<\/div>\n<div id=\"faq-question-1775170974711\" class=\"rank-math-list-item\">\n<h3 class=\"rank-math-question\"><strong>La date PostgreSQL \u00e9quivalente \u00e0 Oracle DATE est TIMESTAMP.<\/strong><\/h3>\n<div class=\"rank-math-answer\">\n\n<p>L'\u00e9quivalent PostgreSQL correct pour Oracle DATE est TIMESTAMP, pas DATE.<br \/>Oracle DATE stocke la date et l'heure (ann\u00e9e, mois, jour, heure, minute, seconde).<br \/>PostgreSQL DATE ne stocke que la date.<br \/>La mise en correspondance d'une Oracle DATE avec une PostgreSQL DATE supprime silencieusement le composant temporel de chaque valeur.<br \/>C'est l'un des probl\u00e8mes de corruption silencieuse des donn\u00e9es les plus courants lors des migrations d'Oracle vers PostgreSQL.<\/p>\n\n<\/div>\n<\/div>\n<div id=\"faq-question-1775170975711\" class=\"rank-math-list-item\">\n<h3 class=\"rank-math-question\"><strong>Comment convertir efficacement les colonnes Oracle NUMBER en PostgreSQL ?<\/strong><\/h3>\n<div class=\"rank-math-answer\">\n\n<p>Analysez la plage et l'\u00e9chelle des donn\u00e9es actuelles pour chaque colonne NUM\u00c9RIQUE avant de proc\u00e9der au mappage.<br \/>Pour les colonnes dont l'\u00e9chelle est 0 (entiers) et qui tiennent dans 32 bits, utilisez INTEGER.<br \/>Pour les colonnes dans la plage de 64 bits, utilisez BIGINT.<br \/>Pour une pr\u00e9cision d\u00e9cimale fixe, utilisez NUMERIC(p,s).<br \/>RESERVER NUMERIC sans pr\u00e9cision pour les colonnes qui n\u00e9cessitent r\u00e9ellement une pr\u00e9cision arbitraire.<br \/>Utilisez la directive ora2pg\u2019s MODIFY_TYPE pour configurer les remplacements au niveau des colonnes.<br \/>Tout mettre par d\u00e9faut sur NUMERIC est correct mais entra\u00eene une d\u00e9gradation mesurable des performances sur les charges de travail enti\u00e8res.<\/p>\n\n<\/div>\n<\/div>\n<div id=\"faq-question-1775170976711\" class=\"rank-math-list-item\">\n<h3 class=\"rank-math-question\"><strong>Que devient le BOOLEAN d'Oracle dans PostgreSQL ?<\/strong><\/h3>\n<div class=\"rank-math-answer\">\n\n<p>Oracle n'avait pas de type d'int\u00e9gralit\u00e9 SQL natif avant la version 23c.<br \/>Les sch\u00e9mas Oracle avant la version 23c utilisaient g\u00e9n\u00e9ralement NUMBER(1) (0\/1) ou CHAR(1) (\u2018O\u2019\/\u2018N\u2019) comme solutions de contournement pour les bool\u00e9ens.<br \/>Ceux-ci ne sont pas automatiquement convertis en BOOLEAN PostgreSQL par les outils de migration.<br \/>Vous devez identifier manuellement ces colonnes, configurer MODIFY_TYPE dans ora2pg pour les mapper \u00e0 BOOLEAN, et mettre \u00e0 jour le code de l'application qui ins\u00e8re ou lit les valeurs 0\/1 ou \u2018Y\u2019\/\u2018N\u2019.<br \/>Les bases de donn\u00e9es Oracle 23c avec des colonnes BOOLEAN natives se traduisent directement en BOOLEAN PostgreSQL.<\/p>\n\n<\/div>\n<\/div>\n<div id=\"faq-question-1775170977711\" class=\"rank-math-list-item\">\n<h3 class=\"rank-math-question\"><strong>PostgreSQL peut-il g\u00e9rer les donn\u00e9es CLOB d'Oracle ?<\/strong><\/h3>\n<div class=\"rank-math-answer\">\n\n<p>Oui.<br \/>TEXT dans PostgreSQL est le mappage correct pour CLOB dans Oracle.<br \/>Le type TEXT de PostgreSQL n'a pas de limite de taille stricte ; les valeurs allant jusqu'\u00e0 environ 1 Go sont g\u00e9r\u00e9es automatiquement via le stockage TOAST.<br \/>La migration des donn\u00e9es elle-m\u00eame est simple.<br \/>Le travail consiste \u00e0 r\u00e9\u00e9crire tout code d'application qui utilise le package DBMS_LOB d'Oracle (DBMS_LOB.READ, DBMS_LOB.WRITE, DBMS_LOB.GETLENGTH, etc.), car ces API LOB sp\u00e9cifiques \u00e0 Oracle n'ont pas d'\u00e9quivalent direct dans PostgreSQL et doivent \u00eatre remplac\u00e9es par des fonctions de cha\u00eene SQL standard.<\/p>\n\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"in-summary\">En r\u00e9sum\u00e9<\/h2>\n\n\n\n<p>La traduction des types de donn\u00e9es Oracle en PostgreSQL n'est pas un exercice univoque.<\/p>\n\n\n\n<p>La plupart des types se traduisent proprement.<\/p>\n\n\n\n<p>Une poign\u00e9e \u2014 DATE, NUMBER, cha\u00eenes vides, solutions de contournement BOOLEAN et ROWID \u2014 n\u00e9cessite des d\u00e9cisions d\u00e9lib\u00e9r\u00e9es et une configuration manuelle.<\/p>\n\n\n\n<p>Les deux r\u00e8gles qui emp\u00eachent la plupart des probl\u00e8mes de donn\u00e9es post-migration :<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Ne jamais mapper Oracle DATE \u00e0 PostgreSQL DATE. Utiliser toujours TIMESTAMP.<\/li>\n\n\n\n<li>N'acceptez jamais NUMERIC pour toutes les colonnes NUMBER. Analysez les plages et utilisez des types entiers lorsque cela est appropri\u00e9.<\/li>\n<\/ul>\n\n\n\n<p>Si vous pr\u00e9voyez une migration d'Oracle vers PostgreSQL et que vous souhaitez d\u00e9finir la strat\u00e9gie de type de donn\u00e9es d\u00e8s le d\u00e9part, <a href=\"https:\/\/rootfan.com\/fr\/services\/\">prendre contact \u2192<\/a><\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>","protected":false},"excerpt":{"rendered":"<p>TL;DR : La plupart des correspondances de types de donn\u00e9es d'Oracle \u00e0 PostgreSQL sont simples. Celles qui sont dangereuses ne le sont pas. Oracle DATE inclut une composante temporelle que PostgreSQL DATE ignore silencieusement. Oracle NUMBER correspond par d\u00e9faut \u00e0 NUMERIC, ce qui est correct mais lent pour les charges de travail enti\u00e8res. Les cha\u00eenes vides dans Oracle sont NULL ; dans PostgreSQL elles ne le sont pas. Ce guide vous donne le tableau complet des correspondances et couvre... <\/p>\n<p class=\"link-more\"><a href=\"https:\/\/rootfan.com\/fr\/oracle-to-postgresql-data-type-mapping\/\" class=\"more-link\">Continuer la lecture<span class=\"screen-reader-text\"> du \u00ab Guide complet de mappage des types de donn\u00e9es Oracle vers PostgreSQL \u00bb<\/span><\/a><\/p>","protected":false},"author":1,"featured_media":6619,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"rank_math_focus_keyword":"oracle to postgresql data type mapping","rank_math_title":"The Complete Oracle-to-PostgreSQL Data Type Mapping Guide","rank_math_description":"Complete Oracle to PostgreSQL data type mapping reference. Covers NUMBER, VARCHAR2, DATE, CLOB, BLOB, and the five dangerous mappings that cause silent data corruption during migration.","rank_math_robots":"","rank_math_og_title":"","rank_math_og_description":"","jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[31,126],"tags":[143,141,137],"class_list":["post-6608","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oracle","category-postgresql","tag-data-migration","tag-data-types","tag-migration"],"jetpack_featured_media_url":"https:\/\/i0.wp.com\/rootfan.com\/wp-content\/uploads\/pexels-photo-36043291.jpeg?fit=1880%2C1253&ssl=1","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/rootfan.com\/fr\/wp-json\/wp\/v2\/posts\/6608","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/rootfan.com\/fr\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/rootfan.com\/fr\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/rootfan.com\/fr\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/rootfan.com\/fr\/wp-json\/wp\/v2\/comments?post=6608"}],"version-history":[{"count":7,"href":"https:\/\/rootfan.com\/fr\/wp-json\/wp\/v2\/posts\/6608\/revisions"}],"predecessor-version":[{"id":6741,"href":"https:\/\/rootfan.com\/fr\/wp-json\/wp\/v2\/posts\/6608\/revisions\/6741"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/rootfan.com\/fr\/wp-json\/wp\/v2\/media\/6619"}],"wp:attachment":[{"href":"https:\/\/rootfan.com\/fr\/wp-json\/wp\/v2\/media?parent=6608"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/rootfan.com\/fr\/wp-json\/wp\/v2\/categories?post=6608"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/rootfan.com\/fr\/wp-json\/wp\/v2\/tags?post=6608"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}