Vous n'êtes pas identifié(e).
Pages : 1
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
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
Merci pour votre réponse.
À 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.
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
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
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
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
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
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
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
Oups, je n'avais pas vu la dernière réponse de Marc. Du coup, je suis d'accord en tout point avec lui
Guillaume.
Hors ligne
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
Pages : 1