IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

SQL Oracle Discussion :

incohérence de donnée


Sujet :

SQL Oracle

  1. #1
    Membre du Club Avatar de restart
    Inscrit en
    Novembre 2009
    Messages
    84
    Détails du profil
    Informations forums :
    Inscription : Novembre 2009
    Messages : 84
    Points : 49
    Points
    49
    Par défaut incohérence de donnée
    bonjour
    je vient de faire une base de donnée d'une bibliothèque
    mon problème c'est que lorsque j'ai fait une requête de sélection la clause where n'as pas accepter la comparaison d'un type de donnée clob avec ce qui es demander
    voici le code de la requête sachant que l'attribu état est de type clob

    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    select exemplaire.numinv,exemplaire.dateachat,exemplaire.etat,exemplaire.livre
    from exemplaire
    where exemplaire.etat='Neuf';

    lorsque je lance cette requete en m'affiche le message d'erreur :
    type de donnée incohérant ;attendu : - ; obtenu : clob

    comment je peux corriger cela svp
    merci

  2. #2
    Modérateur

    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    Août 2006
    Messages
    16 801
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur d'études en informatique
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2006
    Messages : 16 801
    Points : 34 053
    Points
    34 053
    Billets dans le blog
    14
    Par défaut
    Quel est l'intérêt d'avoir mis cette colonne nommée 'etat' de type CLOB ?
    Un simple VARCHAR aurait suffit.

    Et même mieux, une clé étrangère de type entier non signé faisant référence à l'identifiant d'un état figurant dans une table des états.

    Je ne savais même pas que ça existait d'ailleurs ce type !

    D'une manière générale, je n'ai jamais utilisé de type BLOB ou apparenté.

    Un gros texte ou une image ou un objet binaire quelconque se stocke à part, hors de la base de données, laquelle ne stocke que le chemin vers le fichier.
    Ca évite d'avoir des BDD gigantesques pour rien.

    Seul cas de type BLOB que je vois utile : la géomatique. On stocke des corrdonnées de polygones représentant des entités géographiques dans des colonnes de ce type car il y a des outils qui les manipulent directement.

  3. #3
    Membre du Club Avatar de restart
    Inscrit en
    Novembre 2009
    Messages
    84
    Détails du profil
    Informations forums :
    Inscription : Novembre 2009
    Messages : 84
    Points : 49
    Points
    49
    Par défaut
    Citation Envoyé par CinePhil Voir le message
    Quel est l'intérêt d'avoir mis cette colonne nommée 'etat' de type CLOB ?
    Un simple VARCHAR aurait suffit.
    je ne savais pas que un type clob prenais un tel espace mémoire
    mais j'ai pas voulu prendre un type varchar parce que je ne sais pas la taille exacte de ce type
    il y a le varchar(8) varchar (7) etc...
    comment je peux savoir le nombre de caractère stocker dans un varchar(n) avec n un entier donnée

    Citation Envoyé par CinePhil Voir le message

    Et même mieux, une clé étrangère de type entier non signé faisant référence à l'identifiant d'un état figurant dans une table des états.
    si tu pouvais me donner une idée pour résoudre le problème avec cette méthode svp
    j'adore les clés étrangères
    merci

  4. #4
    Modérateur

    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    Août 2006
    Messages
    16 801
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur d'études en informatique
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2006
    Messages : 16 801
    Points : 34 053
    Points
    34 053
    Billets dans le blog
    14
    Par défaut
    Le problème du clob, c'est que pour les index, et donc pour les recherches sur cette colonne, c'est pas top.
    Et là en gros tu te sers d'un dépôt régional d'hypermarché pour y ranger une boîte de sardines !

    Revenons à la modélisations des données.

    Tu as donc des exemplaires qui sont dans un certain état.

    La règle de gestion est la suivante :
    Un exemplaire est d'un seul état et un état peut qualifier plusieurs exemplaires.

    Il en découle le MCD suivant :
    Etat -0,n----Qualifier----1,1- Exemplaire

    Il en découle les tables suivantes :
    Etat (Et_Id, Et_Libelle...)
    Exemplaire (Ex_Id, Ex_IdEtat...)

    Pour la colonne Et_Libelle, un VARCHAR(16) doit largement suffire.
    Dans la liste (Neuf, Bon, Moyen, Mauvais), la longueur maxi est de 7 caractères donc un VARCHAR(8) serait suffisant si tu es sûr de ne pas mettre des libellés plus longs ensuite.

    Quand aux colonnes d'identifiant, ce sont des entiers non nuls, non signés et auto-incrémentés. Les clés étrangères seront de ce fait des entiers non signés.

    Je vois que ta table Exemplaire contient aussi une colonne appelée Livre. Là aussi, il devrait s'agir d'une clé étrangère pointant vers la table des livres.

    Règle de gestion :
    Un livre comporte de 1 à plusieurs exemplaires et un exemplaire se rapporte à un seul livre.

    MCD :
    Livre -1,n----Comporter----1,1- Exemplaire

    Tables :
    Livre (L_Id, L_Titre...)
    Exemplaire (Ex_Id, Ex_IdLivre, Ex_IdEtat...)

    Si tu appliques cette méthode à toutes tes données, tu auras plus de chances d'avoir un schéma normalisé et optimum.

  5. #5
    Membre du Club Avatar de restart
    Inscrit en
    Novembre 2009
    Messages
    84
    Détails du profil
    Informations forums :
    Inscription : Novembre 2009
    Messages : 84
    Points : 49
    Points
    49
    Par défaut
    ouais tu as raison
    j'ai donné trop d'espace mémoire pour les données
    mais pour le varchar(8) c'est une chaine de caractére de longueur conbient exactement
    je veux pas prendre des risques de manque quand meme
    et puit comment je peux modifer le type de la valeur clob en une valeur varchar(8)
    j'ai deja remplis le tableau
    es ce que je dois vider les donnés puit modifier les types des variables ou c'est possible de les modifier sans effacer les données
    j'ai essayer la commande

    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    alter table exemplaire 
    modify etat varchar(8);

    mais ca donne un message d erreur :
    modification non valide des colonnes


    en fete
    je crois que je ne peux pas utiliser la méthaude de cle étranger pour l'état car etat est un attribut de l'entité exemplaire
    ce n'es pas une table lier a la table exemplaire et qui a une cle primere
    on ne peux pas utiliser la méthaude de clé etranger dans ce cas
    vous pensez pas ?

  6. #6
    Modérateur

    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    Août 2006
    Messages
    16 801
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur d'études en informatique
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2006
    Messages : 16 801
    Points : 34 053
    Points
    34 053
    Billets dans le blog
    14
    Par défaut
    pour le varchar(8) c'est une chaine de caractére de longueur conbient exactement
    Ben ce sera au maximum 8 caractères. Le nombre entre parenthèses indique la longueur maxi acceptée dans la colonne.

    comment je peux modifer le type de la valeur clob en une valeur varchar(8)

    j'ai deja remplis le tableau
    Puisque tu as déjà rempli la table (et pas le tableau !), tu peux chercher quelle est la longueur maxi de la colonne etat :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    SELECT MAX(CHARACTER_LENGTH(etat)) AS longueur_etat_maxi
    FROM exemplaire
    Ceci te permettra de calibrer la valeur maxi de ton VARCHAR.

    Ensuite selon ton SGBD, tu peux directement faire une requête ALTER TABLE toute simple ou suivre la méthode plus rigoureuse de SQLPro.

  7. #7
    Membre du Club Avatar de restart
    Inscrit en
    Novembre 2009
    Messages
    84
    Détails du profil
    Informations forums :
    Inscription : Novembre 2009
    Messages : 84
    Points : 49
    Points
    49
    Par défaut
    Citation Envoyé par CinePhil Voir le message
    Ben ce sera au maximum 8 caractères. Le nombre entre parenthèses indique la longueur maxi acceptée dans la colonne.

    Puisque tu as déjà rempli la table (et pas le tableau !), tu peux chercher quelle est la longueur maxi de la colonne etat :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    SELECT MAX(CHARACTER_LENGTH(etat)) AS longueur_etat_maxi
    FROM exemplaire
    Ceci te permettra de calibrer la valeur maxi de ton VARCHAR.
    ok
    vous voulez donc dire varchar(8) c'est un type d'une variable chaine de caractère de longueur 8 ( y compris les espaces)

    es ce que c'est possible , a cette étape, d'éclater le champs etat et de crée une table indépendante de exemplaire identifier par un type et un ID_etat,
    je veux dire après avoir insérer les données dans la table
    es ce que cette modification est possible pour pouvoir appliquer la méthode de clé étrangère
    si la base de donnée était encore vide je pourrais ,par exemple, crée une table etat comme suit :
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    create table etat (
    id_etat number,
    type varchar(8)
    );
    puits effacer l'attribut etat de la table exemplaire comme suit :
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    alter table exemplaire
    drop etat;

    et enfin faire une liaison entre les deux table etat et exemplaire par l'intermediaire d'une clé etranger :
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    alter table etat
    modify id_etat number constraint fk_etat_exemplaire references exemplaire(numinv);

    sauf que dans notre cas j'ai déjà mis les données
    y a t il y moyen de copier les données dans la table etat ,ainsi crée, avant d'effacer l'attribut etat de la table exemplaire
    merci

  8. #8
    Modérateur

    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    Août 2006
    Messages
    16 801
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur d'études en informatique
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2006
    Messages : 16 801
    Points : 34 053
    Points
    34 053
    Billets dans le blog
    14
    Par défaut
    Citation Envoyé par restart Voir le message
    ok
    vous voulez donc dire varchar(8) c'est un type d'une variable chaine de caractére de longueur 8 ( y compris les espaces)
    Oui.
    On peut y stocker des chaînes de caractères de longueur maximum 8 y compris les espaces. Si j'essaie d'y insérer mon prénom, ça passe. Si j'essaie d'y insérer mon nom, il manquera la dernière lettre.

    est ce que c'est possible , a cette étape,d'éclater le champs etat et de crée une table indépendante de exemplaire identifier par un type et un ID_etat,
    je veux dire après avoir insérer les données dans la table
    es ce que cette modification est possible pour pouvoir appliquer la méthode de clé étrangère
    Oui d'une manière générale mais attention aux manipulations si l'application qui utilise la BDD est déjà en route !
    Il faudra aussi modifier les programmes.

    un type et un ID_etat,
    Comment ça un type ?
    S'il s'agit d'un type d'ouvrage (livre, magazine, journal, cassette audio, DVD...) cela se rapporte plutôt à l'ouvrage qu'à l'exemplaire non ?
    Type et Etat sont pour moi deux notions différentes donc deux entités différentes dans le MCD donc deux tables différentes dans la BDD. Et donc deux clés étrangères, dans la tables des ouvrages d'une part et dans la table des exemplaires d'autre part.

  9. #9
    Membre du Club Avatar de restart
    Inscrit en
    Novembre 2009
    Messages
    84
    Détails du profil
    Informations forums :
    Inscription : Novembre 2009
    Messages : 84
    Points : 49
    Points
    49
    Par défaut
    Citation Envoyé par CinePhil Voir le message

    Comment ça un type ?
    S'il s'agit d'un type d'ouvrage (livre, magazine, journal, cassette audio, DVD...) cela se rapporte plutôt à l'ouvrage qu'à l'exemplaire non ?
    Type et Etat sont pour moi deux notions différentes donc deux entités
    non non
    je veux dire que les attributs de la table etat sont id_etat et type_etat
    comment je peux copier les données de l'attribut etat ( de la table exemplaire) dans la table état ainsi crée aprés avoir crée la table état et gérer les clés étrangers

  10. #10
    Modérateur

    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    Août 2006
    Messages
    16 801
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur d'études en informatique
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2006
    Messages : 16 801
    Points : 34 053
    Points
    34 053
    Billets dans le blog
    14
    Par défaut
    Citation Envoyé par restart Voir le message
    non non
    je veux dire que les attributs de la table etat sont id_etat et type_etat
    Je dirais plutôt "Libelle_Etat" mais tu fais comme tu veux.

    comment je peux copier les données de l'attribut etat ( de la table exemplaire) dans la table état ainsi crée aprés avoir crée la table état et gérer les clés étrangers
    1) Créer la table des états.
    2) Copier les valeurs distinctes de la colonne "exemplaire.etat" dans la nouvelle table.
    3) Ajouter une colonne de type entier dans la table "exemplaire".
    4) Mettre à jour la nouvelle colonne de la table "exemplaire" avec l'identifiant de l'état correspondant à la colonne "exemplaire.etat".
    5) Vérifier éventuellement qu'il n'y a pas d'erreur.
    6) Modifier les éventuelles clés étrangères faisant référence à la colonne "exemplaire.etat" actuelle, donc ayant une valeur textuelle.
    7) Modifier les programmes qui utilisent la colonne "exemplaire.etat" ou les clés étrangères mentionnées au 6.
    8) Supprimer la colonne "exemplaire.etat".

  11. #11
    Membre du Club Avatar de restart
    Inscrit en
    Novembre 2009
    Messages
    84
    Détails du profil
    Informations forums :
    Inscription : Novembre 2009
    Messages : 84
    Points : 49
    Points
    49
    Par défaut
    Citation Envoyé par CinePhil Voir le message
    Je dirais plutôt "Libelle_Etat" mais tu fais comme tu veux.
    ouais tu a raison ca serais mieux de l'appeler libelle_etat

    a pars ca si tu pouvais me donner plus d'information sur cela
    Citation Envoyé par CinePhil Voir le message
    2) Copier les valeurs distinctes de la colonne "exemplaire.etat" dans la nouvelle table.
    si vous pouvez me dire la commande qui permet de faire cela
    j'ai jamais fait une chose pareil : copier les données d'une colomne vers une autre colmne d'une table différente

    Citation Envoyé par CinePhil Voir le message
    4) Mettre à jour la nouvelle colonne de la table "exemplaire" avec l'identifiant de l'état correspondant à la colonne "exemplaire.etat".
    j'ai cru que la mise a jour est automatique
    comment je peux faire une mise a jour svp
    pour vérifier que la mise a jour a eux lieu il suffit de voir la table par la commande select
    faire par exemple :
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    select id_etat,libelle_etat 
    from etat;
    mais comment faire une mise a jour de la base de donnée sur place
    merci

  12. #12
    Modérateur

    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    Août 2006
    Messages
    16 801
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur d'études en informatique
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2006
    Messages : 16 801
    Points : 34 053
    Points
    34 053
    Billets dans le blog
    14
    Par défaut
    OK alors je reprends ma chronolgie et je complète avec le code mais je te mache le boulot là !

    Tu n'as pas dit quel est ton SGBD. Je donne le code pour MySQL.

    1) Créer la table des états.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    CREATE TABLE etat (
    id_etat INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY COMMENT 'Identifiant de l''état',
    libelle_etat VARCHAR( 8 ) NOT NULL COMMENT 'Libellé de l''état',
    UNIQUE (
    `libelle_etat`
    )
    ) ENGINE = InnoDB COMMENT = 'Etat des exemplaires des ouvrages';
    A noter : ENGINE = InnoDB pour prise en compte par MySQL des contraintes de clés étrangères. Il faudra que toutes les tables de la BDD utilisent ce moteur sous MySQL sinon adieu les clés étrangères !

    2) Copier les valeurs distinctes de la colonne "exemplaire.etat" dans la nouvelle table.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    INSERT INTO etat (libelle_etat)
    SELECT DISTINCT etat
    FROM exemplaire
    ORDER BY etat;
    3) Ajouter une colonne de type entier dans la table "exemplaire".
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    ALTER TABLE exemplaire ADD id_etat INT UNSIGNED NOT NULL COMMENT 'Identifiant de l''état',
    ADD INDEX ( id_etat )
    4) Mettre à jour la nouvelle colonne de la table "exemplaire" avec l'identifiant de l'état correspondant à la colonne "exemplaire.etat".
    S'il y a beaucoup d'exemplaires et que ce n'est pas déjà fait, mettre au préalable un index sur la colonne exemplaire.etat :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    ALTER TABLE exemplaire
    ADD INDEX (etat)
    Alimentation de la colonne id_etat :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    UPDATE exemplaire AS ex
    INNER JOIN etat AS et ON ex.etat = et.libelle_etat
    SET ex.id_etat = et.id_etat
    5) Vérifier éventuellement qu'il n'y a pas d'erreur.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    SELECT ex.numinv, ex.etat AS etat_origine, et.etat_nouveau
    FROM exemplaire AS ex
    LEFT OUTER JOIN etat AS et ON ex.id_etat = et.id_etat
    WHERE ex.etat <> et.libelle_etat
    ORDER BY ex.numinv
    Si la requête ne retourne aucun résultat, c'est que c'est bon. Sinon, corriger les id_etat qui ne vont pas. Et analyser pourquoi ça a déconné !

    J'ai fait une jointure externe (LEFT OUTER JOIN) au cas où il y aurait des etats qui n'auraient pas été ajoutés dans la table des états. Notamment s'il y a des exemplaire.etat à NULL.

    6) Modifier les éventuelles clés étrangères faisant référence à la colonne "exemplaire.etat" actuelle, donc ayant une valeur textuelle.
    La je ne peux pas faire à ta place vu que je ne connais pas les autres tables de ta BDD mais la démarche est similaire à ci-dessus : création nouvelle colonne numérique puis alimentation en fonction de la valeur textuelle par jointure avec la table des etats.

    Et puis il faut bien que tu bosses un peu !

    7) Modifier les programmes qui utilisent la colonne "exemplaire.etat" ou les clés étrangères mentionnées au 6.
    Là je ne peux pas faire à ta place non plus.

    8) Supprimer la colonne "exemplaire.etat".
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    ALTER TABLE exemplaire
    DROP etat
    A toi d'adapter à ton SGBD.
    Bon courage !

  13. #13
    Membre du Club Avatar de restart
    Inscrit en
    Novembre 2009
    Messages
    84
    Détails du profil
    Informations forums :
    Inscription : Novembre 2009
    Messages : 84
    Points : 49
    Points
    49
    Par défaut
    excuser moi mais j'utilse oracle 10g version express

Discussions similaires

  1. Perte de lien et incohérence de données
    Par PAYASS59 dans le forum Webi
    Réponses: 11
    Dernier message: 05/03/2012, 16h16
  2. étude d'incohérence de données
    Par sanach dans le forum MS SQL Server
    Réponses: 0
    Dernier message: 24/10/2007, 13h25
  3. Erreur ORA-00932 types de données incohérents
    Par paradeofphp dans le forum Oracle
    Réponses: 7
    Dernier message: 21/05/2007, 10h56
  4. ETAT: Incohérence entre le Graphique et les données
    Par Alain LF dans le forum Access
    Réponses: 1
    Dernier message: 02/05/2006, 09h49
  5. types de données incohérents
    Par afaraji dans le forum Oracle
    Réponses: 4
    Dernier message: 22/12/2005, 13h52

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo