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

MS SQL Server Discussion :

Aide pour les transactions SQL server


Sujet :

MS SQL Server

  1. #1
    Futur Membre du Club
    Profil pro
    Étudiant
    Inscrit en
    Août 2008
    Messages
    17
    Détails du profil
    Informations personnelles :
    Âge : 35
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Août 2008
    Messages : 17
    Points : 5
    Points
    5
    Par défaut Aide pour les transactions SQL server
    Bonjour à tous,

    Voilà j'ai un léger problème, je débute avec les transactions et malgré mes recherches je n'arrive pas à comprendre l'erreur, ci-dessous ma procédure suivie de l'erreur renvoyée :
    Code : 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
    CREATE PROCEDURE SupprEd(@titre varchar(64), @complément varchar(128), @V_SORTIE INT =1 OUTPUT)
    as
    declare @t_original varchar(64), @annee varchar(4), @stock int, @cpted int, @bool int
    declare CurEd cursor for(
      select TITRE_ORIGINAL, DATE_DE_SORTIE
      from EDITION
      where TITRE = @titre and COMPLEMENT_DE_TITRE = @complément)
     
    open CurEd
    fetch next from CurEd
    into @t_original, @annee
    -- On teste si l'édition existe, si ce n'est pas le cas, on affiche un message d'erreur
       if(@@FETCH_STATUS != 0) print 'Aucune édition de ce type.'
    -- Tant que le curseur CURED pointe sur un élément, on effectur les opérations suivantes
       begin tran
       while @@FETCH_STATUS = 0
          begin
          -- S'il une réservation a été faite sur l'édition, on affiche un message d'erreur
          if(exists(select * from RESERVATION R where R.TITRE = @titre and R.COMPLEMENT_DE_TITRE = @complément))
             begin
             print 'Une réservation est prévue sur cette édition...'
             set @V_SORTIE = 0
             end
          -- Sinon on supprime l'édition et les stocks correspondants
          else
             begin
             declare CurStockAux cursor for(
                select #STOCK
                   from STOCK
                   where TITRE = @titre and COMPLEMENT_DE_TITRE = @complément)
             open CurStockAux
             fetch next from CurStockAux
             into @stock
             set @cpted = 0
             while @@FETCH_STATUS = 0
                begin
                -- La procédure SupprStock renvoie 1 si elle s'est déroulée correctement, 0 sinon
    	    EXECUTE SupprStock @stock, @V_SORTIE = @bool OUTPUT
                -- Si la suppression d'un élément du stock ne s'est pas effectuée correctement (location en cours),
                -- on annule la transaction.
    	    if(@bool = 0)
                   rollback tran
                set @cpted = @cpted + 1
    	    fetch next from CurStockAux
                into @stock
                end
             close CurStockAux
             deallocate CurStockAux
             delete EDITION where TITRE = @titre and COMPLEMENT_DE_TITRE = @complément
             end
          print 'L''édition ' + @titre + ' : ' + @complément + ' et les stocks correspondants (' + CAST(@cpted as varchar) + ') ont été supprimés de la base.'
          fetch next from CurEd
          into @t_original, @annee
          end
       commit tran
       close CurEd
       deallocate CurEd;
    Serveur : Msg 3902, Niveau 16, État 1, Procédure SupprEd, Ligne 56
    La requête COMMIT TRANSACTION n'a pas de BEGIN TRANSACTION correspondante.
    La procédure SupprStock supprime un élément du stock, sachant qu'une édition peut avoir 0 ou n stock(s) correspondant(s). Ici je souhaite utiliser un transaction car si une location est en cours sur un élément du stock correspondant à l'édition que je désire supprimer, il faudrait annuler toutes les éventuelles suppressions qui pourraient avoir été faites au préallable.

    J'espère avoir été assez clair, en vous remerciant d'avance.

    Cordialement.

  2. #2
    Modérateur

    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Janvier 2005
    Messages
    5 826
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2005
    Messages : 5 826
    Points : 12 371
    Points
    12 371
    Par défaut
    Bonjour,

    C'est normal, vous validez une transaction après peut-être l'avoir défaite ...
    Votre ROLLBACK doit se faire sur une condition dont le ELSE doit contenir le COMMIT.

    De plus :
    - vos transactions doivent être les plus courtes possibles, c'est à dire contenir un minimum d'instructions,

    - vous n'avez pas qualifié vos objets (tables et procédures stockées) avec le nom du schéma auquel ils appartiennent,

    - vous utilisez des accents dans les noms de vos variables et des caractères diacritiques pour le nom de vos colonnes (@complément, #STOCK) ce qui est très dangereux,

    - vous utilisez un curseur à la place de code ensembliste. Retenez qu'un traitement par curseur est au moins 10 fois plus lent que du code ensembliste.

    Je vous ai corrigé la transaction :

    Code : 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
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    CREATE PROCEDURE SupprEd
    	@titre VARCHAR(64),
    	@complément VARCHAR(128),
    	@V_SORTIE INT = 1 OUTPUT
    AS
    BEGIN
    	DECLARE @t_original VARCHAR(64),
    			@annee VARCHAR(4),
    			@stock INT,
    			@cpted INT,
    			@bool INT
     
    	DECLARE CurEd cursor FOR
    	  SELECT TITRE_ORIGINAL, DATE_DE_SORTIE
    	  FROM EDITION
    	  WHERE TITRE = @titre AND COMPLEMENT_DE_TITRE = @complément
    	FOR READ ONLY
     
    	OPEN CurEd
    	FETCH NEXT FROM CurEd INTO @t_original, @annee
    	-- On teste si l'édition existe, si ce n'est pas le cas, on affiche un message d'erreur
    	IF(@@FETCH_STATUS != 0) PRINT 'Aucune édition de ce type.'
    	BEGIN
    		-- Tant que le curseur CURED pointe sur un élément, on effectur les opérations suivantes
    			WHILE @@FETCH_STATUS = 0
    			BEGIN
    				-- S'il une réservation a été faite sur l'édition, on affiche un message d'erreur
    				IF EXISTS
    				(
    					SELECT *
    					FROM RESERVATION R
    					WHERE R.TITRE = @titre
    					AND R.COMPLEMENT_DE_TITRE = @complément
    				)
    				BEGIN
    					PRINT 'Une réservation est prévue sur cette édition...'
    					SET @V_SORTIE = 0
    				END
    				-- Sinon on supprime l'édition et les stocks correspondants
    				ELSE
    				BEGIN
    					DECLARE CurStockAux CURSOR FOR
    						SELECT #STOCK
    						FROM STOCK
    						WHERE TITRE = @titre
    						AND COMPLEMENT_DE_TITRE = @complément
    					FOR READ ONLY
     
    					OPEN CurStockAux
    					FETCH NEXT FROM CurStockAux INTO @stock
    					SET @cpted = 0
     
    					WHILE @@FETCH_STATUS = 0
    					BEGIN
    						BEGIN TRAN
    						-- La procédure SupprStock renvoie 1 si elle s'est déroulée correctement, 0 sinon
    						EXECUTE SupprStock
    							@stock,
    							@V_SORTIE = @bool OUTPUT
     
    						-- Si la suppression d'un élément du stock ne s'est pas effectuée correctement (location en cours),
    						-- on annule la transaction.
    						IF @bool = 0
    						BEGIN
    						   ROLLBACK TRAN
    						END
    						ELSE
    						BEGIN
    							DELETE FROM EDITION
    							WHERE TITRE = @titre
    							AND COMPLEMENT_DE_TITRE = @complément
     
    							COMMIT TRAN
    						END
    					SET @cpted = @cpted + 1
    					FETCH NEXT FROM CurStockAux INTO @stock
    				END
    				CLOSE CurStockAux
    				DEALLOCATE CurStockAux
    			END
    			PRINT 'L''édition ' + @titre + ' : ' + @complément + ' et les stocks correspondants (' + CAST(@cpted AS varchar) + ') ont été supprimés de la base.'
    			FETCH NEXT FROM CurEd INTO @t_original, @annee
    		END
    		CLOSE CurEd
    		DEALLOCATE CurEd
    	END
    END
    @++

  3. #3
    Futur Membre du Club
    Profil pro
    Étudiant
    Inscrit en
    Août 2008
    Messages
    17
    Détails du profil
    Informations personnelles :
    Âge : 35
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Août 2008
    Messages : 17
    Points : 5
    Points
    5
    Par défaut
    Merci elsuket pour ta réponse et tes conseils, je n'ai pas encore vu le code ensembliste mais je tiendrai compte de ta remarque à l'avenir
    Concernant le code, je l'ai testé mais je n'obtiens pas encore ce que je cherche :/

    Imaginons une édition E1 et une liste d'éléments du stock S={S1,S2,S3}. Tous les éléments de S correspondent à E1, en d'autres termes si E1 disparaît on n'a pas lieu de garder S.
    Je rajoute un location L d'un abonné sur S2.
    Avec le code ci-dessus lorsque j'exécute la procédure afin de supprimer E1, celle-ci supprime d'abord S1, bloque sur S2 car il est en location et "s'arrête". Au final seul S1 a été supprimé. Ce que je souhaiterais c'est un résultat "Tout ou rien", est-ce possible ?
    En tout cas je te remercie pour l'interêt que tu portes à mon problème.

    Bonne après-midi.

    Bien cordialement.

  4. #4
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    21 901
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Expert bases de données / SQL / MS SQL Server / Postgresql
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2002
    Messages : 21 901
    Points : 53 143
    Points
    53 143
    Billets dans le blog
    6
    Par défaut
    C'est un simple problème fonctionnel !
    Comptez le nombre de lignes à supprimer au départ.
    Supprimez par une requête DELETE.
    Comptez le nombre de lignes impactées par votre requête DELETE. Si c'est différent faites un ROLLBACK. SI c'est le même, faites un COMMIT.

    C'est vous qui décidez de la façon dont vous voulez que la transaction se termine...

    A +

  5. #5
    Futur Membre du Club
    Profil pro
    Étudiant
    Inscrit en
    Août 2008
    Messages
    17
    Détails du profil
    Informations personnelles :
    Âge : 35
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Août 2008
    Messages : 17
    Points : 5
    Points
    5
    Par défaut
    Bonjour,

    Merci énormément, j'ai revu le code et tout fonctionne à merveille.
    A très bientôt sur le forum ;)

    Bien cordialement.

  6. #6
    Futur Membre du Club
    Profil pro
    Étudiant
    Inscrit en
    Août 2008
    Messages
    17
    Détails du profil
    Informations personnelles :
    Âge : 35
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Août 2008
    Messages : 17
    Points : 5
    Points
    5
    Par défaut
    Bonsoir à tous,

    Finalement je rencontre un autre problème, je n'arrive pas à récupérer la valeur de retour renvoyée par ma procédure SupprStock. La voici :
    Code : 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
    CREATE PROCEDURE SupprStock
       @STOCK INT,
       @V_SORTIE INT =1 OUTPUT
    AS
    BEGIN
       DECLARE @titre varchar(64),
          @annee DATETIME
     
       DECLARE CurStock CURSOR FOR
          SELECT TITRE_ORIGINAL, DATE_DE_SORTIE
          FROM STOCK
          WHERE #STOCK = @STOCK
          FOR READ ONLY
     
       OPEN CurStock
       FETCH NEXT FROM CurStock INTO @titre, @annee
       -- On teste si l'article existe, si ce n'est pas le cas, on affiche un message d'erreur
       IF(@@FETCH_STATUS != 0) PRINT 'Aucun stock portant cet ID.'
       BEGIN
       -- Tant que le curseur CURSTOCK pointe sur un élément, on effectue les opérations suivantes
       WHILE @@FETCH_STATUS = 0
          BEGIN
          -- Si une location est en cours sur cet article, on affiche un message d'erreur
          IF EXISTS
             (
             SELECT *
             FROM LOCATION L
             WHERE L.#Stock = @Stock
             )
             BEGIN
                PRINT 'Une location est toujours en cours...'
                SET @V_SORTIE = 0
             END
             -- Sinon on supprime l'article
          ELSE
             BEGIN
             DELETE FROM STOCK
             WHERE #STOCK = @STOCK
             PRINT 'Le film n°' + CAST(@STOCK as varchar) + ' : ' + @titre + '(' + CAST(YEAR(@annee) as varchar) + ') a été retiré des stocks.'
             END
          FETCH NEXT FROM CurStock INTO @titre, @annee
          END
       END
    CLOSE CurStock
    DEALLOCATE CurStock
    RETURN @V_SORTIE
    END;
    Dans ma seconde procédure SupprEd ci-dessous, j'ai voulu dans un premier temps "printer" ma variable @res, mais rien ne s'affichait. Je l'ai donc initialisé à 0 et je constate que cette valeur reste la même :/ J'imagine donc que je ne m'y prends pas bien pour récupérer la valeur de retour de ma première procédure. Voici la seconde procédure :
    Code : 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
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    CREATE PROCEDURE SupprEd
       @titre VARCHAR(64),
       @complément VARCHAR(128),
       @V_SORTIE INT = 1 OUTPUT
    AS
    BEGIN
       DECLARE @stock INT,
          @nb_Stock INT,
          @nb_Stock_Suppr INT,
          @res INT
     
       DECLARE CurEd cursor FOR
          SELECT *
          FROM EDITION
          WHERE TITRE = @titre AND COMPLEMENT_DE_TITRE = @complément
          FOR READ ONLY
     
       OPEN CurEd
       FETCH NEXT FROM CurEd
       -- On teste si l'édition existe, si ce n'est pas le cas, on affiche un message d'erreur
       IF(@@FETCH_STATUS != 0) PRINT 'Aucune édition de ce type.'
       BEGIN
       -- Tant que le curseur CURED pointe sur un élément, on effectur les opérations suivantes
       WHILE @@FETCH_STATUS = 0
          BEGIN
          -- S'il une réservation a été faite sur l'édition, on affiche un message d'erreur
          IF EXISTS
             (
             SELECT *
             FROM RESERVATION R
             WHERE R.TITRE = @titre
             AND R.COMPLEMENT_DE_TITRE = @complément
             )
             BEGIN
                PRINT 'Une réservation est prévue sur cette édition...'
                SET @V_SORTIE = 0
             END
             -- Sinon on supprime l'édition et les stocks correspondants
          ELSE
             BEGIN
             DECLARE CurStockAux CURSOR FOR
                SELECT #STOCK
                FROM STOCK
                WHERE TITRE = @titre
                AND COMPLEMENT_DE_TITRE = @complément
                FOR READ ONLY
     
             OPEN CurStockAux
             FETCH NEXT FROM CurStockAux INTO @stock
             SET @nb_Stock = 0
             SET @nb_Stock_Suppr = 0
    set @res = 0
     
             BEGIN TRAN SupprEd
             WHILE @@FETCH_STATUS = 0
                BEGIN
                -- La procédure SupprStock renvoie 1 si elle s'est déroulée correctement, 0 sinon
                EXECUTE SupprStock @stock, @V_SORTIE = @res OUTPUT
    print cast(@res as varchar)
                SET @nb_Stock = @nb_Stock + 1
    print cast(@nb_Stock as varchar)
                SET @nb_Stock_Suppr = @nb_Stock_Suppr + @res
    print cast(@nb_Stock_Suppr as varchar)
                FETCH NEXT FROM CurStockAux INTO @stock
                END
             -- Si la suppression d'un élément du stock ne s'est pas effectuée correctement (location en cours),
             -- @nb_Stock != @nb_Stock_Suppr donc on annule la transaction.
             IF @nb_Stock = @nb_Stock_Suppr
                BEGIN
                COMMIT TRAN SupprEd
                DELETE FROM EDITION
                WHERE TITRE = @titre
                AND COMPLEMENT_DE_TITRE = @complément
                PRINT 'L''édition ' + @titre + ' : ' + @complément + ' et les stocks correspondants (' + CAST(@nb_Stock AS varchar) + ') ont été supprimés de la base.'
                END
             ELSE
                BEGIN
                ROLLBACK TRAN SupprEd
                PRINT 'Aucun élément du stock n''a été supprimé, une location est toujours en cours.'
                SET @V_SORTIE = 0
                END
             CLOSE CurStockAux
             DEALLOCATE CurStockAux
             END
          FETCH NEXT FROM CurEd
          END
       CLOSE CurEd
       DEALLOCATE CurEd
       END
    END
    Et enfin le message obtenu lors de l'exécution de SupprEd :
    (1 ligne(s) affectée(s))


    (1 ligne(s) affectée(s))

    Le film n°8 : titre de test2(2008) a été retiré des stocks.
    0
    1
    0

    (1 ligne(s) affectée(s))

    Le film n°9 : titre de test2(2008) a été retiré des stocks.
    0
    2
    0

    (1 ligne(s) affectée(s))

    Le film n°10 : titre de test2(2008) a été retiré des stocks.
    0
    3
    0
    Aucun élément du stock n'a été supprimé, une location est toujours en cours.

    (0 ligne(s) affectée(s))
    En théorie cet appel devrai supprimer les trois éléments du stock (8, 9 et 10) puis l'édition elle-même. Il n'y a aucune location en cours, j'ai vérifié et revérifié ;)

    Merci à ceux qui pourront m'aider.

    Bien cordialement.

  7. #7
    Modérateur

    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Janvier 2005
    Messages
    5 826
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2005
    Messages : 5 826
    Points : 12 371
    Points
    12 371
    Par défaut
    Bonjour,

    @V_SORTIE INT = 1 OUTPUT
    Indique que la variable @V_SORTIE prend la valeur 1 si elle n'est pas valuée lors de son appel (passage en entrée).
    Mais selon votre code, il faut que plusieurs conditions soient remplies pour que celle-ci prenne la valeur 0.

    Vous devriez donc :

    - Remplacer le 1 par NULL, ce qui conserve le statut optionnel de votre paramètre,
    - Valuer @V_SORTIE à 1 juste après le premier BEGIN de votre procédure stockée

    Et parbleu minimisez vos transactions !
    Réécrivez votre procédure stockée avec du code ensembliste : il sera plus clair et surtout plus rapide.
    Si vous ne voyez pas comment faire, postez le DDL de vos tables, et dites-nous en français uniquement ce que vous souhaitez implémenter.

    @++

  8. #8
    Futur Membre du Club
    Profil pro
    Étudiant
    Inscrit en
    Août 2008
    Messages
    17
    Détails du profil
    Informations personnelles :
    Âge : 35
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Août 2008
    Messages : 17
    Points : 5
    Points
    5
    Par défaut
    Bonjour,

    Merci pour l'astuce, ça fonctionne parfaitement ! Et je suis vraiment navré pour ces horribles transactions, à ce jour il s'agit de la seule méthode que nous ayons vu en cours pour éventuellement faire un ROLLBACK si jamais on rencontre un problème.

    Par contre je serais curieux de voir à quoi ressemble un code ensembliste, voici les trois tables sur lesquelles je travaille actuellement :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    CREATE TABLE CATALOGUE(
    TITRE_ORIGINAL VARCHAR(64),
    DATE_DE_SORTIE DATETIME,
    SYNOPSIS VARCHAR(1024),
    SITE_OFFICIEL VARCHAR(64),
    GENRE VARCHAR(64) NOT NULL CHECK(GENRE IN ('Action', 'Animation', 'Aventure', 'Biographie', 'Comédie', 'Comédie dramatique', 'Comédie musicale', 'Comédie romantique', 'Dessin animé', 'Documentaire', 'Drame', 'Erotique', 'Fantastique', 'Guerre', 'Historique', 'Horreur', 'Romance', 'Science-fiction', 'Sport', 'Thriller', 'Western')),
    CATEGORIE VARCHAR(32) NOT NULL CHECK(CATEGORIE IN('Long-métrage', 'Court-métrage', 'Série', 'Pièce de théatre', 'Spectacle')),
    NOTE SMALLINT CHECK(NOTE<=10 AND NOTE>=0),
    PRIMARY KEY(TITRE_ORIGINAL , DATE_DE_SORTIE));
    Code : 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
    CREATE TABLE EDITION(
    TITRE_ORIGINAL VARCHAR(64),
    DATE_DE_SORTIE DATETIME,
    TITRE VARCHAR(64),
    COMPLEMENT_DE_TITRE VARCHAR(128),
    DATE_DE_SORTIE_A_LA_LOCATION DATETIME,
    DUREE SMALLINT CHECK(DUREE>=1 AND DUREE<=5940),
    PUBLICS VARCHAR(16) DEFAULT 'Tout public' CHECK(PUBLICS IN('Tout public','-12','-16','-18')) NOT NULL,
    DISTRIBUTEUR VARCHAR(32),
    SUPPORT VARCHAR(8) CHECK(SUPPORT IN('VHS','DVD','Blu-Ray','Autre')) NOT NULL,
    ZONE SMALLINT DEFAULT '2' CHECK(ZONE>=0 AND ZONE<=8) NOT NULL,
    LANGUE_PRINCIPALE VARCHAR(32) DEFAULT 'Français',
    CODAGE VARCHAR(8) DEFAULT 'PAL' CHECK(CODAGE IN('NTSC','PAL','SECAM','Autre')) NOT NULL,
    COULEUR VARCHAR(16) DEFAULT 'Couleur' CHECK(COULEUR IN('Couleur','Noir et blanc')) NOT NULL,
    CONSTRAINT FK_EDITION FOREIGN KEY (TITRE_ORIGINAL, DATE_DE_SORTIE) REFERENCES CATALOGUE,
    PRIMARY KEY(TITRE_ORIGINAL, DATE_DE_SORTIE, TITRE, COMPLEMENT_DE_TITRE));
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    CREATE TABLE STOCK(
    #STOCK INT IDENTITY(1,1) PRIMARY KEY,
    TITRE_ORIGINAL VARCHAR(64),
    DATE_DE_SORTIE DATETIME,
    TITRE VARCHAR(64),
    COMPLEMENT_DE_TITRE VARCHAR(128),
    USURE VARCHAR(32) DEFAULT 'Bon' CHECK(USURE IN('Bon','Moyen','Illisible')) NOT NULL,
    DISPONIBILITE VARCHAR(32) DEFAULT 'Disponible' CHECK(DISPONIBILITE IN('Disponible','Indisponible')),
    PRIX_PAR_JOUR SMALLINT CHECK(PRIX_PAR_JOUR>1 AND PRIX_PAR_JOUR<=10) NOT NULL,
    CONSTRAINT FK_STOCK FOREIGN KEY (TITRE_ORIGINAL, DATE_DE_SORTIE, TITRE, COMPLEMENT_DE_TITRE) REFERENCES EDITION);
    Elles ne sont certainement pas très "belles", mais nous ne sommes que deux pour faire un boulot de six :/

    Bref il s'agit d'une bribe de la base de donnée que l'on a montée concernant la gestion d'un vidéoclub.
    Un film du catalogue peut avoir 0 ou n édition correspondantes.
    Une édition ne peut avoir qu'un film du catalogue correspondant.
    Une édition peut avoir 0 ou n élément dans le stock correspondant.
    Un élément du stock ne correspond qu'à une édition.

    J'ai donc créé une procédure afin de supprimer un élément du stock, une autre pour supprimer une édition, et enfin une dernière pour supprimer un film du catalogue sachant que :
    1 - Un élément du stock ne peut être supprimé que s'il n'est pas en location.
    2 - Une édition ne peut pas être supprimée si une réservation est prévue sur cette édition.
    3 - Si l'on supprime une édition, on supprime tous les stocks correspondants.
    4 - Si l'on supprime un film du catalogue, on supprime toutes les éditions correspondantes.

    Voici les tables LOCATION et RESERVATION :
    Code : 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 LOCATION(
    #LOCATION INT IDENTITY(1,1) PRIMARY KEY,
    NOM VARCHAR(32),
    PRENOM VARCHAR(32),
    DATE_DE_NAISSANCE DATETIME,
    #ABONNEMENT INT REFERENCES ABONNEMENT(#ABONNEMENT),
    TITRE_ORIGINAL VARCHAR(64),
    DATE_DE_SORTIE DATETIME,
    TITRE VARCHAR(64),
    COMPLEMENT_DE_TITRE VARCHAR(128),
    #STOCK INT REFERENCES STOCK(#STOCK),
    DATE_DE_LOCATION DATETIME NOT NULL DEFAULT GETDATE(),
    DATE_DE_RETOUR DATETIME NOT NULL,
    CONSTRAINT FK_LOCATION FOREIGN KEY (NOM, PRENOM, DATE_DE_NAISSANCE) REFERENCES ABONNE,
    CONSTRAINT FK2_LOCATION FOREIGN KEY (TITRE_ORIGINAL, DATE_DE_SORTIE, TITRE, COMPLEMENT_DE_TITRE) REFERENCES EDITION);
    Code : 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 RESERVATION(
    #RESERVATION INT IDENTITY(1,1) PRIMARY KEY,
    NOM VARCHAR(32),
    PRENOM VARCHAR(32),
    DATE_DE_NAISSANCE DATETIME,
    NOM_TYPE VARCHAR(32),
    #ABONNEMENT INT REFERENCES ABONNEMENT(#ABONNEMENT),
    TITRE_ORIGINAL VARCHAR(64),
    DATE_DE_SORTIE DATETIME,
    TITRE VARCHAR(64),
    COMPLEMENT_DE_TITRE VARCHAR(128),
    DATE_DE_RESERVATION DATETIME,
    DATE_DE_RETOUR_ESTIMEE DATETIME,
    CONSTRAINT FK_RESERVATION FOREIGN KEY (NOM, PRENOM, DATE_DE_NAISSANCE) REFERENCES ABONNE,
    CONSTRAINT FK2_RESERVATION FOREIGN KEY (TITRE_ORIGINAL, DATE_DE_SORTIE, TITRE, COMPLEMENT_DE_TITRE) REFERENCES EDITION);
    Voilà tout. J'ai eut la réponse à ma question donc je laisse ces trois tables seulement pour ceux qui auront le temps et l'envie de me montrer à quoi ressemblerait une procédure utilisant un code ensembliste.

    Merci encore pour tout.

    Bien cordialement.

  9. #9
    Modérateur

    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Janvier 2005
    Messages
    5 826
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2005
    Messages : 5 826
    Points : 12 371
    Points
    12 371
    Par défaut
    Bonjour,

    Je regarde ça dès que j'ai un peu plus de temps.

    @++

Discussions similaires

  1. Problème compte de domaine pour les services sql server
    Par philwood dans le forum Administration
    Réponses: 15
    Dernier message: 16/03/2012, 16h36
  2. Pour débuter avec SQL Server : les triggers
    Par asprogramer dans le forum Développement
    Réponses: 2
    Dernier message: 02/04/2010, 04h44
  3. aide pour les transactions
    Par looping dans le forum Débuter
    Réponses: 6
    Dernier message: 01/05/2009, 22h00
  4. Réponses: 2
    Dernier message: 04/11/2006, 00h33
  5. Choisir Oracle ou Sql-Server pour les transactions ?
    Par Roronoa01 dans le forum Décisions SGBD
    Réponses: 4
    Dernier message: 06/11/2005, 22h41

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