Création d'un numéro chrono dans ue procédure [Résolu]

NHenry 14280 Messages postés vendredi 14 mars 2003Date d'inscription 22 octobre 2018 Dernière intervention - 8 mai 2012 à 15:01 - Dernière réponse : NHenry 14280 Messages postés vendredi 14 mars 2003Date d'inscription 22 octobre 2018 Dernière intervention
- 14 mai 2012 à 21:02
Bonjour,

Dans le cadre d'un projet, je dois générer un numéro chronologique à certains enregistrements.

Ces enregistrements peuvent avoir plusieurs numéro chronologiques.

Données sources :
DateId, référence vers la date de l'évènement
ResId, référence vers la réservation
ChronoNum, numéro chronologique (unique pour chaque date)

Une date peut avoir plusieurs réservations qui elles-mêmes peuvent avoir plusieurs numéro chrono (si plusieurs places réservées).

Ce que je voudrais faire, c'est une procédure stockée qui accepterais en paramètre :
L'Id de la date
L'Id de la résa
Le nombre de numéro chrono à générer

Les numéros auto-incrémentés ne sont exploitable ici, car les numéros chrono doivent être unique ET consécutif pour chaque date (Départ à 1).

Mon souci est qu'apparemment, on ne peux pas faire d'INSERT de données venant de la même table, voici 2 versions que j'ai essayé :
CREATE PROCEDURE InsertChrono(pDateId INT, pResSubId INT, pNb INT)
BEGIN
WHILE pNb > 0 DO
INSERT INTO ReservationChrono 
(ChronoDate, ChronoRes, ChronoNum) 
VALUES 
(
pDateId, pResSubId, 
(
SELECT MAX(ChronoNum)+1 
FROM ReservationChrono 
WHERE ChronoDate=pDateId
)
);
SET pNb = pNb - 1;
END WHILE;
END


CREATE PROCEDURE InsertChrono(pDateId INT, pResSubId INT, pNb INT)
BEGIN
WHILE pNb > 0 DO
INSERT INTO ReservationChrono 
(ChronoDate, ChronoRes, ChronoNum) 
VALUES 
(SELECT pDateId, pResSubId, MAX(ChronoNum)+1 
FROM ReservationChrono 
WHERE ChronoDate=pDateId)
);
SET pNb = pNb - 1;
END WHILE;
END


L'erreur est toujours vers le SELECT.

Je pensais que j'avais une solution, mais apparemment, non.
Auriez-vous des conseils, des techniques à utiliser, ou autre aide afin de remplir la fonction désirée ?

Je précise que je ne maitrise pas cette partie de SQL, je me contente le plus souvent des instructions de base.

Merci d'avance.

Afficher la suite 

Votre réponse

5 réponses

Meilleure réponse
cs_jopop 1540 Messages postés lundi 26 mai 2003Date d'inscription 1 août 2013 Dernière intervention - 10 mai 2012 à 15:19
3
Merci
Salut,

pour résumer :
* l'archi c'est :
DATE <--1,n-- RESA <--1,n-- CHRONO
* et tu cherches à initialiser n CHRONO pour une DATE et une RESA donnée
j'ai bon ?

Ce que je comprends pas trop c'est le coup du MAX :
- si tu n'as encore aucun CHRONO pour cette DATE/RESA, ça renverra null,
- tu cherches le MAX mais ensuite tu décrémentes ton compteur.

Bon, quoi qu'il en soit : un INSERT SELECT ne doit pas contenir de VALUES.
INSERT INTO table1 (champ1)
SELECT champ1 FROM table2;

Merci cs_jopop 3

Avec quelques mots c'est encore mieux Ajouter un commentaire

Codes Sources a aidé 101 internautes ce mois-ci

Commenter la réponse de cs_jopop
Meilleure réponse
cs_jopop 1540 Messages postés lundi 26 mai 2003Date d'inscription 1 août 2013 Dernière intervention - 14 mai 2012 à 09:37
3
Merci
Re,

donc déjà un souci de moins (INSERT SELECT sans VALUES).

Sinon je suis allé revoir les de la proc stock sur le SDZ. On peut noter deux trucs dans ce doc :
- les assignations se font avec l'opérateur ":=",
- il est possible de changer de délimiteur (perso j'ai eu des soucis de scripts qui passaient pas avec le délimiteur ';' sur la commande 'mysql source'), à voir si c'est utile dans ton cas. A voir.

Sinon j'ai testé ça qui fonctionne sous TOAD :
CREATE FUNCTION maFunc(iMonParam INT) RETURNS INT
BEGIN
  DECLARE iMaLocal INT;
  SET iMaLocal := 10 + iMonParam;
  RETURN iMaLocal;
END;

SELECT maFunc(10);

A noter que pour vérifier le bon fonctionnement j'en ai fait une fonction, ce qui apporte quelques différences :
- le RETURNS pour le type de retour, le RETURN pour le retour,
- pas de "sens" au paramètre (IN, OUT ou INOUT)
Sinon c'est tout pareil. Je pense donc que ton souci est l'opérateur d'assignation.

Merci cs_jopop 3

Avec quelques mots c'est encore mieux Ajouter un commentaire

Codes Sources a aidé 101 internautes ce mois-ci

Commenter la réponse de cs_jopop
Meilleure réponse
NHenry 14280 Messages postés vendredi 14 mars 2003Date d'inscription 22 octobre 2018 Dernière intervention - 14 mai 2012 à 21:02
3
Merci
Bonjour,

Merci avec tes conseils, j'ai changé le délimiteur, voici le code fonctionnel pour ceux que ça intéresse :
DELIMITER |
CREATE PROCEDURE InsertChrono(pDateId INT, pResSubId INT, pNb INT)
BEGIN
WHILE pNb > 0 DO
INSERT INTO ReservationChrono 
(ChronoDate, ChronoRes, ChronoNum) 
SELECT pDateId, pResSubId, IFNULL(MAX(ChronoNum)+1 ,1)
FROM ReservationChrono 
WHERE ChronoDate=pDateId;
SET pNb := pNb - 1;
END WHILE;
END


Je n'ai pas vu ce tutoriel durant mes recherches, mais j'avoue que je n'aurais pas cherché du côté du délimiteur.

Parfois en informatique, il ne faut pas chercher à comprendre ...

---------------------------------------------------------------------
[list=ordered][*]Pour poser correctement une question et optimiser vos chances d'obtenir des réponses, pensez à lire le règlement CS, celui-ci pour bien poser votre question ou encore celui-ci pour les PFE et autres exercices[*]Quand vous postez un code, merci d'utiliser la coloration syntaxique (3ième icône en partant de la droite : )
[*]En VB.NET pensez à activer Option Explicit et Option Strict (propriété du projet) et à retirer l'import automatique de l'espace de nom Microsoft.VisualVasic (onglet Références dans les propriétés du projet).
[*]Si votre problème est résolu (et uniquement si c'est le cas), pensez à mettre "Réponse acceptée" sur le ou les messages qui vous ont aidés./list
---

Merci NHenry 3

Avec quelques mots c'est encore mieux Ajouter un commentaire

Codes Sources a aidé 101 internautes ce mois-ci

Commenter la réponse de NHenry
NHenry 14280 Messages postés vendredi 14 mars 2003Date d'inscription 22 octobre 2018 Dernière intervention - 10 mai 2012 à 19:57
0
Merci
Bonjour,

"* l'archi c'est :
DATE <--1,n-- RESA <--1,n-- CHRONO "
En effet, c'est bien ça.

"et tu cherches à initialiser n CHRONO pour une DATE et une RESA donnée "
Oui, mais un numéro unique pour une date, pour la réservation (enfin pour une place, une résa contenant plusieurs places).

Donc en plus clair :
Date <- 1,n - Résa <- 1,n - Place <- 1,1 - Chrono

Et donc, je cherche à obtenir un numéro unique pour la date, identifiant la place.
Ce numéro est unique, sans trou et commence à 1 pour chaque date.
Donc pour plusieurs dates, je peux avoir le même numéro chrono, mais dans une date, je n'ai aucun doublon.

Concernant le MAX et la décrémentation, c'est pour générer respectivement un numéro consécutif pour une date et pour générer autant de numéro qu'il y a de place (un FOR en somme).

J'espère avoir été clair.

---------------------------------------------------------------------
[list=ordered][*]Pour poser correctement une question et optimiser vos chances d'obtenir des réponses, pensez à lire le règlement CS, celui-ci pour bien poser votre question ou encore celui-ci pour les PFE et autres exercices[*]Quand vous postez un code, merci d'utiliser la coloration syntaxique (3ième icône en partant de la droite : )
[*]En VB.NET pensez à activer Option Explicit et Option Strict (propriété du projet) et à retirer l'import automatique de l'espace de nom Microsoft.VisualVasic (onglet Références dans les propriétés du projet).
[*]Si votre problème est résolu (et uniquement si c'est le cas), pensez à mettre "Réponse acceptée" sur le ou les messages qui vous ont aidés./list
---
Commenter la réponse de NHenry
NHenry 14280 Messages postés vendredi 14 mars 2003Date d'inscription 22 octobre 2018 Dernière intervention - 12 mai 2012 à 17:07
0
Merci
Bonjour,

Après quelques tentatives, j'ai fais fonctionner :
INSERT INTO ReservationChrono 
(ChronoDate, ChronoRes, ChronoNum) 
SELECT 1, 1, IFNULL(MAX(ChronoNum)+1,1)
FROM ReservationChrono 
WHERE ChronoDate=1;


Mais ma procédure ne passe toujours pas :
CREATE PROCEDURE InsertChrono(pDateId INT, pResSubId INT, pNb INT)
BEGIN
WHILE pNb > 0 DO
INSERT INTO ReservationChrono 
(ChronoDate, ChronoRes, ChronoNum) 
SELECT pDateId, pResSubId, IFNULL(MAX(ChronoNum)+1 ,1)
FROM ReservationChrono 
WHERE ChronoDate=pDateId;
SET pNb = pNb - 1;
END WHILE;
END

#1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '' at line 8
Soit la ligne de
WHERE ChronoDate=pDateId;

Sinon, j'ai aussi essayé :
CREATE PROCEDURE InsertChrono(IN pDateId INT, IN pResSubId INT, IN pNb INT)
BEGIN
DECLARE lCounter INT;
SET lCounter=0;
WHILE lCounter < pNb DO
INSERT INTO ReservationChrono 
(ChronoDate, ChronoRes, ChronoNum) 
SELECT pDateId, pResSubId, IFNULL(MAX(ChronoNum)+1 ,1)
FROM ReservationChrono 
WHERE ChronoDate=pDateId;
SET lCounter = lCounter + 1;
END WHILE;
END

#1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '' at line 3
Soit sur le DECLARE ...

Je ne comprend pas pourquoi, avez-vous une idée ?
Apparemment, c'est un MySql 5.0.

Je continue de chercher.

---------------------------------------------------------------------
[list=ordered][*]Pour poser correctement une question et optimiser vos chances d'obtenir des réponses, pensez à lire le règlement CS, celui-ci pour bien poser votre question ou encore celui-ci pour les PFE et autres exercices[*]Quand vous postez un code, merci d'utiliser la coloration syntaxique (3ième icône en partant de la droite : )
[*]En VB.NET pensez à activer Option Explicit et Option Strict (propriété du projet) et à retirer l'import automatique de l'espace de nom Microsoft.VisualVasic (onglet Références dans les propriétés du projet).
[*]Si votre problème est résolu (et uniquement si c'est le cas), pensez à mettre "Réponse acceptée" sur le ou les messages qui vous ont aidés./list
---
Commenter la réponse de NHenry

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.