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

Schéma Discussion :

cardinalité 0,N ou 1,N ? [MCD]


Sujet :

Schéma

  1. #1
    Expert confirmé
    Avatar de laurentSc
    Homme Profil pro
    Webmaster débutant perpétuel !
    Inscrit en
    octobre 2006
    Messages
    8 685
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 57
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Webmaster débutant perpétuel !
    Secteur : Industrie

    Informations forums :
    Inscription : octobre 2006
    Messages : 8 685
    Points : 4 179
    Points
    4 179
    Billets dans le blog
    1
    Par défaut cardinalité 0,N ou 1,N ?
    Bonjour,

    je me demande s'il est important de choisir entre ces 2 cardinalités au niveau du MCD, sachant que si je compare le SQL généré dans les 2 cas par Looping, il est identique...Du coup, quel intérêt ?

    exemple de MCD :
    Nom : cardinalite.png
Affichages : 86
Taille : 12,1 Ko
    En gros, c'est simple : un utilisateur soumet des tickets ; j'ai choisi 1,N et non 0,N car s'il soumet 0 ticket alors il n'existe pas. Ai-je bien fait ?

    De toute façon, SQL généré avec 0,N :
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    CREATE TABLE US_user(
       US_ident INT UNSIGNED AUTO_INCREMENT,
       US_firstname VARCHAR(50),
       US_lastname VARCHAR(50),
       PRIMARY KEY(US_ident)
    );
     
    CREATE TABLE TI_ticket(
       TI_ident INT UNSIGNED AUTO_INCREMENT,
       TI_num_ticket BIGINT NOT NULL,
       US_ident_SBM INT UNSIGNED NOT NULL,
       PRIMARY KEY(TI_ident),
       UNIQUE(TI_num_ticket),
       FOREIGN KEY(US_ident_SBM) REFERENCES US_user(US_ident)
    );

    SQL généré avec 1,N :
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    CREATE TABLE US_user(
       US_ident INT UNSIGNED AUTO_INCREMENT,
       US_firstname VARCHAR(50),
       US_lastname VARCHAR(50),
       PRIMARY KEY(US_ident)
    );
     
    CREATE TABLE TI_ticket(
       TI_ident INT UNSIGNED AUTO_INCREMENT,
       TI_num_ticket BIGINT NOT NULL,
       US_ident_SBM INT UNSIGNED NOT NULL,
       PRIMARY KEY(TI_ident),
       UNIQUE(TI_num_ticket),
       FOREIGN KEY(US_ident_SBM) REFERENCES US_user(US_ident)
    );

    Ca me semble identique, donc aucune importance...Où est-ce que je me trompe ?
    Il vaut mieux viser la perfection et la manquer que viser l'imperfection et l'atteindre. - Bertrand Russell

  2. #2
    Modérateur
    Avatar de escartefigue
    Homme Profil pro
    bourreau
    Inscrit en
    mars 2010
    Messages
    7 417
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loir et Cher (Centre)

    Informations professionnelles :
    Activité : bourreau
    Secteur : Finance

    Informations forums :
    Inscription : mars 2010
    Messages : 7 417
    Points : 23 885
    Points
    23 885
    Billets dans le blog
    2
    Par défaut
    Le choix des cardinalités du MCD doit être la conséquence exacte des règles de gestion, or, choisir 1,n de l'utilisateur vers le ticket signifie que sans ticket, un utilisateur ne peut pas exister.
    Il est peu probable que ça corresponde à la réalité

  3. #3
    Expert confirmé
    Avatar de laurentSc
    Homme Profil pro
    Webmaster débutant perpétuel !
    Inscrit en
    octobre 2006
    Messages
    8 685
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 57
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Webmaster débutant perpétuel !
    Secteur : Industrie

    Informations forums :
    Inscription : octobre 2006
    Messages : 8 685
    Points : 4 179
    Points
    4 179
    Billets dans le blog
    1
    Par défaut
    Merci pour votre réponse,

    j'avais montré ce MCD en le simplifiant, mais en réalité, c'est celui-là :

    Nom : MCD28x900.png
Affichages : 57
Taille : 17,4 Ko

    Règles de gestion :

    Règle (FR) Règle (EN) statut
    R015a Un ticket est soumis par 1 et 1 seul utilisateur-submitter A ticket is submitted by 1 and only 1 user-submitter
    R015b Un utilisateur-submitter soumet 1 à 1 N ticket(s) A user-submitter submits 1 to N ticket (s)
    Donc si le submitter ne crée pas un ticket, il n'existe pas...

    PS : j'ai complété le tableau des règles de gestion montré ici https://www.developpez.net/forums/d2.../#post11741189. J'ai supprimé les règles qui ne contenaient que des listes d'attribut, mais je ne le donne pas car il reste 31 règles (facile de compter avec Excel ) et je pense qu'il manque encore 2 ou 3 règles.

    EDIT : à mon avis, erreur de logique car s'il n'est pas submitter, il existe quand même ; OK ?
    Donc, OK, on respecte les règles de gestion, mais il n'y a aucune différence au niveau du SQL généré, donc à quoi ça sert ?
    Il vaut mieux viser la perfection et la manquer que viser l'imperfection et l'atteindre. - Bertrand Russell

  4. #4
    Modérateur
    Avatar de escartefigue
    Homme Profil pro
    bourreau
    Inscrit en
    mars 2010
    Messages
    7 417
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loir et Cher (Centre)

    Informations professionnelles :
    Activité : bourreau
    Secteur : Finance

    Informations forums :
    Inscription : mars 2010
    Messages : 7 417
    Points : 23 885
    Points
    23 885
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par laurentSc Voir le message
    à mon avis, erreur de logique car s'il n'est pas submitter, il existe quand même ; OK ?
    C'est très probable, sauf s'il s'agit d'une hot line qui crée l'occurrence de USER lors de l'appel, en même temps que l'opérateur crée l'occurrence de TICKET.
    S'il s'agit d'un ticket créé au sein d'une entreprise alors toutes les personnes de l'entreprise sont crées même si elles n'ont jamais déclaré d'incident.

  5. #5
    Expert confirmé
    Avatar de laurentSc
    Homme Profil pro
    Webmaster débutant perpétuel !
    Inscrit en
    octobre 2006
    Messages
    8 685
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 57
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Webmaster débutant perpétuel !
    Secteur : Industrie

    Informations forums :
    Inscription : octobre 2006
    Messages : 8 685
    Points : 4 179
    Points
    4 179
    Billets dans le blog
    1
    Par défaut
    OK pour la valeur de la cardinalité, par contre , et ça ?

    Citation Envoyé par laurentSc Voir le message
    mais il n'y a aucune différence au niveau du SQL généré, donc à quoi ça sert ?
    Il vaut mieux viser la perfection et la manquer que viser l'imperfection et l'atteindre. - Bertrand Russell

  6. #6
    Modérateur
    Avatar de escartefigue
    Homme Profil pro
    bourreau
    Inscrit en
    mars 2010
    Messages
    7 417
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loir et Cher (Centre)

    Informations professionnelles :
    Activité : bourreau
    Secteur : Finance

    Informations forums :
    Inscription : mars 2010
    Messages : 7 417
    Points : 23 885
    Points
    23 885
    Billets dans le blog
    2
    Par défaut
    Si on voulait exiger la présence d'un ticket pour pouvoir créer le user, il faudrait ne "commiter" la transaction que pour insert ticket+user.

  7. #7
    Expert confirmé
    Avatar de laurentSc
    Homme Profil pro
    Webmaster débutant perpétuel !
    Inscrit en
    octobre 2006
    Messages
    8 685
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 57
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Webmaster débutant perpétuel !
    Secteur : Industrie

    Informations forums :
    Inscription : octobre 2006
    Messages : 8 685
    Points : 4 179
    Points
    4 179
    Billets dans le blog
    1
    Par défaut
    OK,

    ne connaissant commit que de nom, j'ai regardé https://baptiste-wicht.developpez.co...ver/securiser/. Même si ça parle de sql-server au lieu de MySQL, j'ai compris le principe. A mon avis, si je code les requêtes avec bon sens, pas besoin ; OK ?
    Il vaut mieux viser la perfection et la manquer que viser l'imperfection et l'atteindre. - Bertrand Russell

  8. #8
    Modérateur

    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    août 2006
    Messages
    16 661
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 58
    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 661
    Points : 33 677
    Points
    33 677
    Billets dans le blog
    13
    Par défaut
    MCD :
    A -1,1----associer----1,n- B

    La table issue de A contient une clé étrangère référençant B.
    Mais comme un B ne peut pas exister sans être associé à un A, il faut alors créer des procédures SQL d'ajout de données pour empêcher qu'un B soit créé sans association avec un A, d'une part ; et pour créer en même temps que le A un B s'il n'existe pas déjà.

    La structure des tables ne change effectivement pas si on met 0,n ou 1,n côté B mais dans le cas de 0,n, on peut se contenter de simples requêtes INSERT au lieu de procédures, même si ce n'est pas forcément la meilleure pratique. Un programme devrait en effet toujours agir sur les données des tables via des procédures.

    A mon avis, si je code les requêtes avec bon sens, pas besoin ; OK ?
    Techniquement, puisque la structure des tables est identique quelles que soient les cardinalités que vous mettez côté B, le SGBD ne vous empêchera pas de créer un B via une requête INSERT sans qu'il soit associé à un A mais alors votre BDD devient (temporairement) incohérente avec votre modèle. Si pour une raison ou une autre le A n'est finalement pas créé, vous avez créé un B qui n'est pas associé à un A.
    Par contre, si vous créez un A et que la colonne référençant B ne correspond à aucune valeur dans B, vous aurez une erreur de clé étrangère et le système empêchera la création du A sans B existant en face.
    Philippe Leménager. Ingénieur d'étude à l'École Nationale Supérieure de Formation de l'Enseignement Agricole. Autoentrepreneur.
    Mon ancien blog sur la conception des BDD, le langage SQL, le PHP... et mon nouveau blog sur les mêmes sujets.
    « Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément ». (Nicolas Boileau)
    À la maison comme au bureau, j'utilise la suite Linux Mageïa !

  9. #9
    Expert confirmé
    Avatar de laurentSc
    Homme Profil pro
    Webmaster débutant perpétuel !
    Inscrit en
    octobre 2006
    Messages
    8 685
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 57
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Webmaster débutant perpétuel !
    Secteur : Industrie

    Informations forums :
    Inscription : octobre 2006
    Messages : 8 685
    Points : 4 179
    Points
    4 179
    Billets dans le blog
    1
    Par défaut
    Merci pour votre réponse, CinePhil.

    Citation Envoyé par CinePhil Voir le message
    on peut se contenter de simples requêtes INSERT au lieu de procédures, même si ce n'est pas forcément la meilleure pratique. Un programme devrait en effet toujours agir sur les données des tables via des procédures.
    Quand vous parlez de procédures, il s'agit bien des procédures stockées ? Ne connaissant pas du tout, j'ai entré dans Google, SQL procédure, et ça m'a tout de suite proposé des articles sur les procédures stockées.

    Citation Envoyé par CinePhil Voir le message
    Techniquement, puisque la structure des tables est identique quelles que soient les cardinalités que vous mettez côté B, le SGBD ne vous empêchera pas de créer un B via une requête INSERT sans qu'il soit associé à un A mais alors votre BDD devient (temporairement) incohérente avec votre modèle. Si pour une raison ou une autre le A n'est finalement pas créé, vous avez créé un B qui n'est pas associé à un A.
    Par contre, si vous créez un A et que la colonne référençant B ne correspond à aucune valeur dans B, vous aurez une erreur de clé étrangère et le système empêchera la création du A sans B existant en face.
    En lisant ça, j'en déduis qu'il faudra d'abord créer (s'il n'existe pas déjà) B avant A. OK ?
    Il vaut mieux viser la perfection et la manquer que viser l'imperfection et l'atteindre. - Bertrand Russell

  10. #10
    Modérateur

    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    août 2006
    Messages
    16 661
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 58
    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 661
    Points : 33 677
    Points
    33 677
    Billets dans le blog
    13
    Par défaut
    Quand vous parlez de procédures, il s'agit bien des procédures stockées ?
    Oui.

    En lisant ça, j'en déduis qu'il faudra d'abord créer (s'il n'existe pas déjà) B avant A. OK ?
    Oui. Et donc il vaut mieux encapsuler ça dans une procédure stockée.

    Vite fait, en MariaDB (MySQL), ça donne un truc de ce genre :
    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    DELIMITER //
    CREATE OR REPLACE PROCEDURE pi_ajout_ticket
    (
        INOUT id_submitter INTEGER, -- identifiant de l'utilisateur qui soumet la demande
        IN firsname VARCHAR(50), -- Prénom de l'utilisateur
        IN lastname VARCHAR(50), -- Nom de l'utilisateur
        IN objet TEXT, -- Objet du ticket 
        OUT id_ticket INTEGER -- identifiant du ticket
    )
    /************************************************************************************************
    Base :			pef
    Objet :			Procédure
    Auteur :		Philippe Leménager
    Version :		V 0.1 - plemenager - 2021-07-05 - Création
    Description : 	Procédure d'ajout d'un ticket avec contrôle de l'existence du submitter
    Utilise :		US_user, TI_ticket
    Historique :	
     
    *************************************************************************************************/
    BEGIN
        DECLARE ctr_exception CONDITION FOR SQLSTATE '23000'; -- Erreur de contrainte
    	DECLARE EXIT HANDLER FOR ctr_exception
    		BEGIN
    			GET DIAGNOSTICS @nb_errors = NUMBER;
    			GET DIAGNOSTICS CONDITION @nb_errors
    				@errno = MYSQL_ERRNO, @text = MESSAGE_TEXT;
     
    			IF LOCATE('fk_US_ident_SBM', @text) > 0 THEN 
    				SET @errno = 10019;
    				SET @text = 'Identifiant du submitter inconnu';
    			END IF;
     
    			SIGNAL SQLSTATE VALUE '23000'
    			SET MYSQL_ERRNO = @errno, MESSAGE_TEXT = @text;
    		END;
     
        -- Vérification de l'existence du submitter et création éventuelle
        IF id_submitter IS NULL OR id_submitter < 1 THEN
            -- id_submitter non fourni => on cherche avec le nom et le prénom
            IF firstname IS NULL OR CHAR_LENGHT(firstname) < 1
                OR lastname IS NULL OR CHAR_LENGTH(lastname) < 1 THEN 
                -- Identité non fournie => Erreur
                SIGNAL SQLSTATE VALUE '45000'
                SET MYSQL_ERRNO = 10001, MESSAGE_TEXT = 'Identifiant ou identité du submiter non fourni !';
            ELSE
                -- Recherche du submitter par son nom et son prénom
                SELECT US_ident INTO id_submitter
                FROM US_user
                WHERE US_firstname = firstname
                    AND US_lastname = lastname;
     
                IF id_submitter IS NULL OR id_submitter < 1 THEN
                    -- Submitter non trouvé => on le crée
                    INSERT INTO US_user (US_firstname, US_lastname)
                    VALUES (firsname, lastname);
     
                    SET id_submitter = LAST_INSERT_ID();
                END IF;
            END IF;
        END IF;
     
        -- Création du ticket
        INSERT INTO TI_ticket(US_ident_SBM, TI_objet)
        VALUES (id_submitter, objet);
     
        SET id_ticket = LAST_INSERT_ID();
    END; //
    DELIMITER ;
    Nota :
    1) pas vérifié ni testé !
    2) Je ne vois pas l'utilité de la colonne TI_num_ticket BIGINT NOT NULL en plus de la clé primaire TI_ident INT UNSIGNED AUTO_INCREMENT alors je ne l'ai pas pris en compte dans ma procédure.
    3) J'ai par contre ajouté l'objet du ticket qui, il me semble, manque à votre table. Ceci dit, je n'ai pas lu toutes les discussions que vous avez lancées sur votre projet.
    Philippe Leménager. Ingénieur d'étude à l'École Nationale Supérieure de Formation de l'Enseignement Agricole. Autoentrepreneur.
    Mon ancien blog sur la conception des BDD, le langage SQL, le PHP... et mon nouveau blog sur les mêmes sujets.
    « Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément ». (Nicolas Boileau)
    À la maison comme au bureau, j'utilise la suite Linux Mageïa !

  11. #11
    Expert confirmé
    Avatar de laurentSc
    Homme Profil pro
    Webmaster débutant perpétuel !
    Inscrit en
    octobre 2006
    Messages
    8 685
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 57
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Webmaster débutant perpétuel !
    Secteur : Industrie

    Informations forums :
    Inscription : octobre 2006
    Messages : 8 685
    Points : 4 179
    Points
    4 179
    Billets dans le blog
    1
    Par défaut
    Merci pour votre proposition de procédure stockée.

    Comme je ne connais pas du tout, j'aurais été bien incapable de faire cela ! Pour comprendre un minimum, n'ayant rien trouvé dans DVP, j'ai regardé https://openclassrooms.com/fr/course...dures-stockees. Connaissez-vous mieux pour s'initier ?

    J'ai compris la majeure partie de votre code, néanmoins, quelques questions :

    - SELECT US_ident INTO id_submitter FROM US_user : ça ressemble à une requête SQL, sauf le INTO id_submitter, où id_submitter est un paramètre INOUT passé à la procédure ; pouvez-vous en dire plus ?

    - pouvez-vous décoder IF LOCATE('fk_US_ident_SBM', @text) > 0 ?

    - si j'ai bien compris, les variables sont écrites @VARXYZ. Donc quelle est la signification de termes comme SQLSTATE, MYSQL_ERRNO ou MESSAGE_TEXT ?

    - Les codes d'erreur que vous mettez dans SQLSTATE ou dans MYSQL_ERRNO ont probablement une signification. Pouvez-vous en dire plus ?
    Il vaut mieux viser la perfection et la manquer que viser l'imperfection et l'atteindre. - Bertrand Russell

  12. #12
    Modérateur

    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    août 2006
    Messages
    16 661
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 58
    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 661
    Points : 33 677
    Points
    33 677
    Billets dans le blog
    13
    Par défaut
    - SELECT US_ident INTO id_submitter FROM US_user : ça ressemble à une requête SQL, sauf le INTO id_submitter, où id_submitter est un paramètre INOUT passé à la procédure ; pouvez-vous en dire plus ?
    Oui, les paramètres peuvent être valorisés à l'appel de la procédure ou modifiés durant la procédure.
    Un SELECT US_ident INTO id_submitter va affecter automatiquement le résultat du SELECT au paramètre id_submitter. Bien entendu, il ne faut faire ça que si on est sûr d'avoir une seule ligne en réponse au SELECT, ce qui ne serait pas forcément le cas ici car il peut y avoir des homonymes. Il faudrait davantage de caractères discriminants et, d'ailleurs, si possible, mettre une clé UNIQUE sur un ensemble de colonnes. Mais, là encore, je n'ai pas lu toutes vos discussions donc je ne sais pas si ce point a été évoqué.
    Avec ma procédure, soit on fournit à la procédure l'identifiant du submitter s'il est déjà connu par le programme, soit on fournit le nom et le prénom et c'est la procédure qui cherche le submitter et le crée s'il n'est pas trouvé.

    - pouvez-vous décoder IF LOCATE('fk_US_ident_SBM', @text) > 0 ?

    - si j'ai bien compris, les variables sont écrites @VARXYZ. Donc quelle est la signification de termes comme SQLSTATE, MYSQL_ERRNO ou MESSAGE_TEXT ?

    - Les codes d'erreur que vous mettez dans SQLSTATE ou dans MYSQL_ERRNO ont probablement une signification. Pouvez-vous en dire plus ?
    La première partie de la procédure définit un handler d'erreur. Il s'agit ici de détecter les erreurs et de fournir au programme un message d'erreur explicite.
    Vous pouvez lire mon billet de blog à ce sujet.
    Philippe Leménager. Ingénieur d'étude à l'École Nationale Supérieure de Formation de l'Enseignement Agricole. Autoentrepreneur.
    Mon ancien blog sur la conception des BDD, le langage SQL, le PHP... et mon nouveau blog sur les mêmes sujets.
    « Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément ». (Nicolas Boileau)
    À la maison comme au bureau, j'utilise la suite Linux Mageïa !

  13. #13
    Expert confirmé
    Avatar de laurentSc
    Homme Profil pro
    Webmaster débutant perpétuel !
    Inscrit en
    octobre 2006
    Messages
    8 685
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 57
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Webmaster débutant perpétuel !
    Secteur : Industrie

    Informations forums :
    Inscription : octobre 2006
    Messages : 8 685
    Points : 4 179
    Points
    4 179
    Billets dans le blog
    1
    Par défaut
    grâce à votre blog, je comprends presque tout. Néanmoins j'ai encore du mal avec ces 2 lignes :
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    DECLARE ctr_exception CONDITION FOR SQLSTATE '23000'; -- Erreur de contrainte
    	DECLARE EXIT HANDLER FOR ctr_exception

    D'autre part, au lieu de recourir aux procédures stockées, que pensez-vous d'utiliser les transactions (commit, rollback, etc) ?
    Il vaut mieux viser la perfection et la manquer que viser l'imperfection et l'atteindre. - Bertrand Russell

  14. #14
    Modérateur

    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    août 2006
    Messages
    16 661
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 58
    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 661
    Points : 33 677
    Points
    33 677
    Billets dans le blog
    13
    Par défaut
    Il s'agit de déclarer un handler d'exception qui sera utilisé par le SGBD en cas d'erreur relevée par celui-ci. Exemple : le nom respect d'une contrainte de clé étrangère enclenchera une erreur par le SGBD. Il faut donc déclarer le handler avec l'instruction DECLARE EXIT HANDLER FOR ctr_exception.
    Et comme on peut potentiellement déclarer plusieurs handlers d'exception, on désigne dans cette ligne dans quelle condition utiliser ce handler, via FOR ctr_exception. ce ctr_exception est un nom de condition qui est déclarée à la ligne juste au dessus : DECLARE ctr_exception CONDITION FOR SQLSTATE '23000'; -- Erreur de contrainte.

    Donc on commence par déclarer une condition pour les erreurs de type 23000 et on utilise ensuite le nom ctr_exception dans l'initialisation du handler. Comme indiqué dans le commentaire, le code 23000 est pour les erreurs de non respect de contrainte (clés étrangères, unicité...). Un autre type d'erreur ne serait pas traité par le handler et le SGBD renverrait son texte d'erreur standard, souvent difficilement compréhensible par l'utilisateur lambda, si on lui affiche l'erreur tel quel.

    Cette syntaxe de gestion d'erreur par MySQL / MariaDB est un peu complexe à comprendre au début mais on s'y habitue.
    Philippe Leménager. Ingénieur d'étude à l'École Nationale Supérieure de Formation de l'Enseignement Agricole. Autoentrepreneur.
    Mon ancien blog sur la conception des BDD, le langage SQL, le PHP... et mon nouveau blog sur les mêmes sujets.
    « Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément ». (Nicolas Boileau)
    À la maison comme au bureau, j'utilise la suite Linux Mageïa !

  15. #15
    Modérateur
    Avatar de escartefigue
    Homme Profil pro
    bourreau
    Inscrit en
    mars 2010
    Messages
    7 417
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loir et Cher (Centre)

    Informations professionnelles :
    Activité : bourreau
    Secteur : Finance

    Informations forums :
    Inscription : mars 2010
    Messages : 7 417
    Points : 23 885
    Points
    23 885
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par laurentSc Voir le message
    OK,

    ne connaissant commit que de nom, j'ai regardé https://baptiste-wicht.developpez.co...ver/securiser/. Même si ça parle de sql-server au lieu de MySQL, j'ai compris le principe. A mon avis, si je code les requêtes avec bon sens, pas besoin ; OK ?
    Les notions de transactions sont fondamentales. L'enjeu est la cohérence du contenu de la base de données. Les contraintes d'intégrité n'y suffisent pas ni la qualité des requêtes.
    Il est donc essentiel de maîtriser ce concept.

  16. #16
    Expert confirmé
    Avatar de laurentSc
    Homme Profil pro
    Webmaster débutant perpétuel !
    Inscrit en
    octobre 2006
    Messages
    8 685
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 57
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Webmaster débutant perpétuel !
    Secteur : Industrie

    Informations forums :
    Inscription : octobre 2006
    Messages : 8 685
    Points : 4 179
    Points
    4 179
    Billets dans le blog
    1
    Par défaut
    Je commence à regarder. Ca a l'air plus simple que les procédures stockées :
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    -- on désactive l'autocommit (nécessaire pour MySQL)
    SET autocommit = 0;
    -- on lance la transaction
    START TRANSACTION;
    -- les requêtes SQL
    if NO ERROR
        COMMIT;
    else
        ROLLBACK;
    La classe PHP PdoPlusPlus de Rawsrc les prend en charge. Comme j'utilise cette classe, je regarde comment faire...
    Il vaut mieux viser la perfection et la manquer que viser l'imperfection et l'atteindre. - Bertrand Russell

  17. #17
    Modérateur

    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    août 2006
    Messages
    16 661
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 58
    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 661
    Points : 33 677
    Points
    33 677
    Billets dans le blog
    13
    Par défaut
    L'avantage d'une procédure stockée est que tout est fait dans le SGBD avec une seule connexion. Ce qui n'empêche pas de lancer les SART TRANSACTION et COMMIT ou ROLLBACK en dehors de la procédure. On peut aussi gérer la transaction à l'intérieur d'une procédure mais c'est un peu plus délicat s'il y a une procédure qui en utilise une autre.
    Philippe Leménager. Ingénieur d'étude à l'École Nationale Supérieure de Formation de l'Enseignement Agricole. Autoentrepreneur.
    Mon ancien blog sur la conception des BDD, le langage SQL, le PHP... et mon nouveau blog sur les mêmes sujets.
    « Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément ». (Nicolas Boileau)
    À la maison comme au bureau, j'utilise la suite Linux Mageïa !

  18. #18
    Expert confirmé
    Avatar de laurentSc
    Homme Profil pro
    Webmaster débutant perpétuel !
    Inscrit en
    octobre 2006
    Messages
    8 685
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 57
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Webmaster débutant perpétuel !
    Secteur : Industrie

    Informations forums :
    Inscription : octobre 2006
    Messages : 8 685
    Points : 4 179
    Points
    4 179
    Billets dans le blog
    1
    Par défaut
    Peut-être, mais vu mon niveau, je préfère rester dans un domaine que je maîtrise.

    Au fait, je réponds à certains de vos points :

    Citation Envoyé par CinePhil Voir le message
    2) Je ne vois pas l'utilité de la colonne TI_num_ticket BIGINT NOT NULL en plus de la clé primaire TI_ident INT UNSIGNED AUTO_INCREMENT alors je ne l'ai pas pris en compte dans ma procédure.
    3) J'ai par contre ajouté l'objet du ticket qui, il me semble, manque à votre table. Ceci dit, je n'ai pas lu toutes les discussions que vous avez lancées sur votre projet.
    Le fait de créer la rubrique TI_ident, c'est pour avoir une clé primaire plus concise, vu le type de la rubrique TI_num_ticket.

    L'objet du ticket existe ; simplement, pour alléger le post, j'avais simplifié la classe TI_ticket...
    Il vaut mieux viser la perfection et la manquer que viser l'imperfection et l'atteindre. - Bertrand Russell

  19. #19
    Modérateur

    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    août 2006
    Messages
    16 661
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 58
    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 661
    Points : 33 677
    Points
    33 677
    Billets dans le blog
    13
    Par défaut
    Le fait de créer la rubrique TI_ident, c'est pour avoir une clé primaire plus concise, vu le type de la rubrique TI_num_ticket.
    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    CREATE TABLE TI_ticket(
       TI_ident INT UNSIGNED AUTO_INCREMENT,
       TI_num_ticket BIGINT NOT NULL,
       US_ident_SBM INT UNSIGNED NOT NULL,
       PRIMARY KEY(TI_ident),
       UNIQUE(TI_num_ticket),
       FOREIGN KEY(US_ident_SBM) REFERENCES US_user(US_ident)
    );
    Soit le numéro de ticket est un entier qui est incrémenté à chaque nouveau ticket et est donc équivalent, au type près, à la clé primaire TI_ident ; soit c'est un code composé de chiffres et je ne suis pas sûr que le BIGINT soit le meilleur choix.
    D'alleurs, il est un peu paradoxal d'avoir une colonne pouvant accueillir potentiellement un plus grand nombre de lignes (TI_num_ticket de type BIGINT) que la colonne clé primaire (de type INT). Soit vous envisagez vraiment d'avoir un si grand nombre de tickets que le BIGINT UNSIGNED s'impose et il faut que la clé primaire puisse accueillir autant de tickets, donc être aussi de type BIGINT UNSIGNED, soit vous avez vu trop grand et il conviendrait de réduire le type du numéro de ticket.
    Philippe Leménager. Ingénieur d'étude à l'École Nationale Supérieure de Formation de l'Enseignement Agricole. Autoentrepreneur.
    Mon ancien blog sur la conception des BDD, le langage SQL, le PHP... et mon nouveau blog sur les mêmes sujets.
    « Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément ». (Nicolas Boileau)
    À la maison comme au bureau, j'utilise la suite Linux Mageïa !

  20. #20
    Expert confirmé
    Avatar de laurentSc
    Homme Profil pro
    Webmaster débutant perpétuel !
    Inscrit en
    octobre 2006
    Messages
    8 685
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 57
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Webmaster débutant perpétuel !
    Secteur : Industrie

    Informations forums :
    Inscription : octobre 2006
    Messages : 8 685
    Points : 4 179
    Points
    4 179
    Billets dans le blog
    1
    Par défaut
    Effectivement, si la clé primaire est de type INT, il n'était pas logique d'avoir un attribut NUM_ticket de type BIGINT. Ayant regardé, le type INT suffit, et du coup, je l'ai mis en clé primaire.
    Il vaut mieux viser la perfection et la manquer que viser l'imperfection et l'atteindre. - Bertrand Russell

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. Cardinalité dans PHPMyAdmin
    Par xmag dans le forum Requêtes
    Réponses: 1
    Dernier message: 19/08/2005, 09h31
  2. Récupérer les cardinalités
    Par Invité dans le forum MS SQL Server
    Réponses: 3
    Dernier message: 11/08/2005, 09h12
  3. [Together] Gestion des cardinalités
    Par cladsam dans le forum Autres
    Réponses: 3
    Dernier message: 03/08/2005, 21h33
  4. cardinalité
    Par star_light dans le forum Décisions SGBD
    Réponses: 8
    Dernier message: 30/12/2004, 17h59
  5. Cardinalités
    Par Pingwin dans le forum Diagrammes de Classes
    Réponses: 6
    Dernier message: 30/01/2003, 18h22

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