PostgreSQL La base de donnees la plus sophistiquee au monde.

Forums PostgreSQL.fr

Le forum officiel de la communauté francophone de PostgreSQL

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

#1 31/08/2010 13:57:27

Esab75
Membre

Valeur vide / NULL dans un champ de type numérique

Bonjour,

J'aurais besoin de votre aide SVP.

Nous avons une application PHP tournant sous MYSQL, et nous avons besoin d'utiliser PostgreSQL pour un client.

le probleme est que lorsque nous insérons des chaines vides dans un champ de type numerique, nous obtenons une erreur.

Je pense qu'il faudrait en fait utiliser NULL au lieu de la chaine vide .

Cependant nous aimerions eviter d'avoir à recoder toutes les requetes de notre application, ma question c'est de savoir s'il est possible au niveau de la structure d'une table (ou ailleur) de faire en sorte que notre colonne de type numérique accepte les valeurs vides ? ou bien les convertissent en NULL ?


J'ai regardé sur le forum, ainsi que sur google je n'ai pas trouvé grand chose.

Dans la documentation j'ai vu qu'il est possible de définir ses propres types, est il possible par exemple de creer un type basé sur numerique et de faire en sorte qu'il accepte nos valeurs vides ?
Si oui comment faire ? je n'ai trouvé de solution

Merci

Hors ligne

#2 31/08/2010 14:20:32

Marc Cousin
Membre

Re : Valeur vide / NULL dans un champ de type numérique

Une chaîne vide est une valeur de type chaîne. Elle n'est donc pas utilisable pour un type numérique. À quelle valeur numérique pourrait on faire correspondre une chaîne vide ?

Vous feriez mieux d'utiliser NULL pour le code mysql et le code postgresql. Cela marchera pour les deux moteurs.

Sinon oui, on doit pouvoir bidouiller un type qui accepte des conversions de chaîne de ce type. Mais ce n'est clairement pas la bonne approche.


Marc.

Hors ligne

#3 31/08/2010 14:43:02

Esab75
Membre

Re : Valeur vide / NULL dans un champ de type numérique

Merci pour votre réponse.

Marc Cousin a écrit :

À quelle valeur numérique pourrait on faire correspondre une chaîne vide ?

J'aimerais que celà correspond à NULL.

Je sais que le probleme viens du code SQL, on me le dit sur plusieurs forums,  l'application est ancienne et je n'ai pas les moyens d'optimiser tout le code SQL de l'application pour le moment, c'est pour ça que je souhaiterais trouver une solution ou un hack en attendant de pouvoir le faire.

Marc Cousin a écrit :

Sinon oui, on doit pouvoir bidouiller un type qui accepte des conversions de chaîne de ce type.

Je n'ai pas trouvé comment faire, quelqu'un aurait il un exemple ?

Merci de votre aide.

Hors ligne

#4 31/08/2010 14:55:53

Marc Cousin
Membre

Re : Valeur vide / NULL dans un champ de type numérique

Un exemple probablement pas, vu que comme je vous l'ai dit avant, c'est le genre de choses qu'il ne faut pas faire.

Néanmoins, ce qui vous intéresse estCREATE CAST (http://docs.postgresql.fr/8.4/sql-createcast.html) pour créer des fonctions de transtypage entre les différents types. Je présume par ailleurs que votre version de PostgreSQL est assez ancienne ? (sinon vous n'auriez même pas de cast automatique de votre chaîne vers un numérique).


Marc.

Hors ligne

#5 31/08/2010 15:10:51

flo
Membre

Re : Valeur vide / NULL dans un champ de type numérique

Et comme solution temporaire, créer un trigger avant l'insertion pour convertir les chaines  vides en null? C'est certes lourd, mais cela permettrait de ne pas modifier la structure des données, en attendant la correction des requêtes. S'il n'est vraiment pas envisageable de les mettre à jour tout de suite...
Evidemment, il faut espérer dans ce cas qu'il n'y ait pas de grosses opérations de mises à jour ou d'insertion, sinon je suppose que les performances risqueraient de s'en ressentir.

Marc, t'en penses quoi?

Hors ligne

#6 31/08/2010 15:20:57

Marc Cousin
Membre

Re : Valeur vide / NULL dans un champ de type numérique

Que le trigger sera déclenché après le cast. Et que je pense que c'est le cast de '' en numeric qui pose problème. D'où la question sur la version de PostgreSQL: sur 8.3 et supérieur, ce cast n'existe même plus à ma connaissance.


Marc.

Hors ligne

#7 31/08/2010 16:19:56

Esab75
Membre

Re : Valeur vide / NULL dans un champ de type numérique

Merci pour vos réponses.

Nous n'avons aucun souci sous MySQL, Oracle ou SQL Server pour insérer une chaine vide dans un champ numerique, il n'y a que postgreSQL qui nous pose ce probleme.

@Marc Cousin : la version utilisée est la 8.4. Le lien que vous m'avez donné pour CREATE CAST est bien pour la 8.4

J'ai regardé la documentation, je ne suis pas certain d'avoir bien compris.

En gros il faudrait creer un type perso (par exemple mynumeric) et l'assigner a tout mes champs de type numeric, c'est a dire modifier la structure de toutes mes tables ?

puis faire un CREATE CAST (toto AS numeric) WITH FUNCTION doMyCast(toto) AS IMPLICIT;

avec le code de la fonction equivalent à :

function doMyCast(toto)
{
if (toto =='') {
return NULL
} else {
return toto
}
}

et cette "conversion/transtypage" serait automatique sur toute la base ?

Je ne comprends pas .



@flo : Nous avons pensé à la solution du trigger mais il faudrait mettre un trigger sur toutes les tables, il y en a beaucoup c'est lourd, et celà affecterait beaucoup les performances .



Merci de votre aide.

Hors ligne

#8 31/08/2010 17:07:00

Marc Cousin
Membre

Re : Valeur vide / NULL dans un champ de type numérique

Pour le premier point :
- Vous n'avez aucun problème avec MySQL, c'est normal, il n'est pas vraiment réputé pour sa rigueur quant à la validation de données
- Pour Oracle, c'est un cas particulier (et à ma connaissance une non conformité à SQL) : une chaine vide vaut NULL. Donc il convertit vers NULL votre chaîne avant de la convertir vers un entier.
Pour SQL Server, aucune idée du pourquoi.

Tout ça simplement pour dire que ce n'est pas parce que PostgreSQL refuse que c'est de sa faute : il valide vos données.

Après recherche, la seule solution pour contourner votre problème (autre que la solution simple d'écrire du code SQL correct bien sûr) est de créer un nouveau type de base : la conversion entre le type texte et le type integer ne peut pas apparemment pas être modifiée : le bon fonctionnement de PostgreSQL dépend bien sûr de la présence de ces opérateurs.

Pour créer un nouveau type de base, il faut écrire des procédures stockées en C, le but final étant de pouvoir définir de nouvelles fonctions d'entrées sorties sur ce type.

Je reviens donc à la proposition initiale : corrigez le code.


Marc.

Hors ligne

#9 31/08/2010 17:17:45

gleu
Administrateur

Re : Valeur vide / NULL dans un champ de type numérique

J'ai du mal à croire que ce que propose Marc soit possible. J'arrive au bon résultat mais il faut ajouter une conversion vers le type texte pour chaque donnée numérique à insérer (ou mettre à jour). Autrement dit modifier toutes les requêtes qui utilisent le type. Et dans ce cas-là, autant le faire correctement en indiquant NULL plutôt qu'une chaîne vide.


Guillaume.

Hors ligne

#10 31/08/2010 17:18:44

gleu
Administrateur

Re : Valeur vide / NULL dans un champ de type numérique

Oups, je n'avais pas vu la dernière réponse de Marc. Du coup, je suis d'accord en tout point avec lui smile


Guillaume.

Hors ligne

#11 31/08/2010 17:33:31

Esab75
Membre

Re : Valeur vide / NULL dans un champ de type numérique

Merci à tous de vous être penchés sur le probleme.
Nous avons posé la question sur d'autres forums, il n'y a apparement pas de solution simple / rapide, nous allons probablement voir avec le client pour utiliser un autre SGBD en attendant une future version de l'application qui corrigera le code SQL.
Cordialement.

Hors ligne

Pied de page des forums