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 Procédural MySQL Discussion :

Correction des auto-incréments


Sujet :

SQL Procédural MySQL

  1. #1
    Modérateur

    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    Août 2006
    Messages
    16 799
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    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 799
    Points : 34 032
    Points
    34 032
    Billets dans le blog
    14
    Par défaut Correction des auto-incréments
    Bonjour,

    Je récupère une série de BDD dans lesquelles la valeur de l'auto_incrément n'a pas été enregistré avec la sauvegarde de la BDD. Ce qui fait qu'à l'insertion de lignes, cela génère des erreurs d'id déjà existant. Par exemple, pour MariaDB, l'auto_increment est à 12 mais l'id 12 existe déjà dans la table, ainsi que 13, 14...

    Comme il y a beaucoup de tables, je souhaite, dans chaque table ayant un id auto_incrémenté, affecter la valeur du MAX(id) +1 à l'auto_incrément.

    Dans ma procédure, je dois donc, pour une BDD donnée en paramètre, parcourir d'abord la liste des tables et récupérer la valeur de l'auto_increment puis la liste des colonnes de chaque table pour modifier les bonnes colonnes.

    Voici ma procédure en premier jet :
    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
    DELIMITER //
    CREATE OR REPLACE PROCEDURE pr_fix_auto_increment
    (
    	IN nom_bdd VARCHAR(32),
    	OUT resultat VARCHAR(255)
    )
    BEGIN
    	DECLARE nom_table VARCHAR(48) DEFAULT NULL;
    	DECLARE nom_colonne VARCHAR(48) DEFAULT NULL; 
    	DECLARE nb INT DEFAULT 0;
    	DECLARE autoinc INT DEFAULT NULL;
    	DECLARE max_id INT DEFAULT NULL;
    	DECLARE data_type VARCHAR(48) DEFAULT NULL;
    	DECLARE is_nullable CHAR(3) DEFAULT NULL;
    	DECLARE comment VARCHAR(255) DEFAULT NULL;
    	DECLARE extra VARCHAR(48) DEFAULT NULL;
    	DECLARE requete VARCHAR(255);
     
    	SELECT COUNT(*) INTO nb
    	FROM information_schema.SCHEMATA
    	WHERE SCHEMA_NAME = nom_bdd;
     
    	IF nb = 0 THEN 
    		SIGNAL SQLSTATE VALUE '45000'
    		SET MYSQL_ERRNO = 10027, MESSAGE_TEXT = 'Base de données inexistante';
    	END IF;
     
    	DECLARE liste_tables CURSOR FOR 
    		SELECT TABLE_NAME, AUTO_INCREMENT
    		FROM information_schema.TABLES
    		WHERE TABLE_SCHEMA = nom_bdd;
    	DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
     
    	OPEN liste_tables;
     
    	read_loop: LOOP
    		FETCH liste_tables INTO nom_table, autoinc;
     
    		IF done THEN
    			LEAVE read_loop;
    		END IF;
     
    		DECLARE liste_colonnes CURSOR FOR SELECT COLUMN_NAME, DATA_TYPE, EXTRA, COMMENT FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = nom_bdd;
    		DECLARE CONTINUE HANDLER FOR NOT SET done2 = TRUE;
     
    		OPEN liste_colonnes;
     
    		read_loop2: LOOP
    			FETCH liste_colonnes INTO nom_colonne, data_type, extra, comment;
     
    			IF done2 THEN
    				LEAVE read_loop2;
    			END IF;
     
    			IF extra = 'auto_increment' THEN
    				SET requete = CONCAT('SELECT MAX(', nom_colonne, ') INTO max_id FROM ', nom_bdd, '.', nom_table);
    				PREPARE stmt FROM requete;
    				EXECUTE stmt;
    				DEALLOCATE stmt;
     
    				IF max_id > autoinc THEN
    					SET requete = CONCAT('ALTER TABLE ', nom_bdd, '.', nom_table, 
    										' MODIFY ', nom_colonne, ' ', data_type, 
    										' NOT NULL AUTO_INCREMENT COMMENT ', "'", comment, "', AUTO_INCREMENT = ", max_id + 1);
    					PREPARE stmt FROM requete;
    					EXECUTE stmt;
    					DEALLOCATE stmt;
    				END IF;
    			END IF;
    		END LOOP;
     
    		CLOSE liste_colonnes;
     
    	END LOOP;
     
    	SET resultat = CONCAT('Base de données ', nom_bdd, 'traitée.';
    END; //
    DELIMITER ;
    Lorsque j'injecte ce code dans phpMyAdmin, voilà ce que j'obtiens :
    Citation Envoyé par MariaDB
    #1064 - Erreur de syntaxe près de 'DECLARE liste_tables CURSOR FOR SELECT TABLE_NAME, AUTO_INCREMENT FROM inform...' à la ligne 27
    Je ne vois pas quelle erreur de syntaxe j'ai à cet endroit !

    Par ailleurs, est-ce qu'on peut, comme je l'ai fait, faire un curseur à l'intérieur du parcours d'un curseur ?

    Ou bien y a t-il une autre méthode pour faire ce que je souhaite ?
    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 !

  2. #2
    Modérateur

    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    Août 2006
    Messages
    16 799
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    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 799
    Points : 34 032
    Points
    34 032
    Billets dans le blog
    14
    Par défaut
    Trouvé !

    Il faut que les DECLARE soient tous en premier. On ne peut pas en mettre, semble t-il, au milieu du code.

    Du coup j'ai simplifié ma procédure parce que je me suis rendu compte que je n'avais besoin que d'un seul cursor.

    Voici la procédure finale :
    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
    CREATE OR REPLACE PROCEDURE test.pr_fix_auto_increment
    (
    	IN nom_bdd VARCHAR(32),
    	OUT resultat VARCHAR(255)
    )
    /************************************************************************************************
    Base :			test
    Objet :			Procédure
    Auteur :		Philippe Leménager
    Version :		V 1.0 - plemenager - 2023-10-28 - Création
    Description : 	Met l'auto-incrément d'une table à la valeur max de l'id +1
    Utilise :		information_schema.SCHEMATA - Liste des BDD
    				information_schema.TABLES - Liste des tables
    				information_schema.COLUMNS - Liste des colonnes
    Historique :	
    **************************************************************************************************/
    BEGIN
    	DECLARE nom_table VARCHAR(48) DEFAULT NULL;
    	DECLARE nom_colonne VARCHAR(48) DEFAULT NULL; 
    	DECLARE nb INT DEFAULT 0;
    	DECLARE autoinc INT DEFAULT NULL;
    	DECLARE max_id INT DEFAULT NULL;
    	DECLARE data_type VARCHAR(48) DEFAULT NULL;
    	DECLARE is_nullable CHAR(3) DEFAULT NULL;
    	DECLARE comment VARCHAR(255) DEFAULT NULL;
    	DECLARE extra VARCHAR(48) DEFAULT NULL;
    	DECLARE requete VARCHAR(255);
    	DECLARE done BOOLEAN DEFAULT FALSE;
    	DECLARE liste_colonnes CURSOR FOR 
    		SELECT TABLE_NAME, COLUMN_NAME, DATA_TYPE, EXTRA, COMMENT 
    		FROM information_schema.COLUMNS 
    		WHERE TABLE_SCHEMA = nom_bdd;
    	DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
     
    	-- Vérification que la BDD existe
    	SELECT COUNT(*) INTO nb
    	FROM information_schema.SCHEMATA
    	WHERE SCHEMA_NAME = nom_bdd;
     
    	IF nb = 0 THEN 
    		SIGNAL SQLSTATE VALUE '45000'
    		SET MYSQL_ERRNO = 10027, MESSAGE_TEXT = 'Base de données inexistante';
    	END IF;
     
    	-- Parcours des colonnes de la BDD
    	OPEN liste_colonnes;
     
    	read_loop: LOOP
    		FETCH liste_colonnes INTO nom_table, nom_colonne, data_type, extra, comment;
     
    		-- Si fin de BDD alors sortie
    		IF done THEN
    			LEAVE read_loop;
    		END IF;
     
    		-- Traitement de la colonne en auto_increment
    		IF extra = 'auto_increment' THEN
    			-- Récupération de la valeur de l'auto-incrément de la table
    			SELECT `AUTO_INCREMENT` INTO autoinc 
    			FROM information_schema.TABLES
    			WHERE TABLE_NAME = nom_table;
     
    			-- Récupération de l'identifiant max de la table
    			SET requete = CONCAT('SELECT MAX(', nom_colonne, ') INTO max_id FROM ', nom_bdd, '.', nom_table);
    			PREPARE stmt FROM requete;
    			EXECUTE stmt;
    			DEALLOCATE PREPARE stmt;
     
    			-- Si l'identifiant max est supérieur à l'auto-incrément, on change l'auto-incrément
    			IF max_id > autoinc THEN
    				SET requete = CONCAT('ALTER TABLE ', nom_bdd, '.', nom_table, 
    									' MODIFY ', nom_colonne, ' ', data_type, 
    									' NOT NULL AUTO_INCREMENT COMMENT ', "'", comment, "', AUTO_INCREMENT = ", max_id + 1);
    				PREPARE stmt FROM requete;
    				EXECUTE stmt;
    				DEALLOCATE PREPARE stmt;
    			END IF;
    		END IF;
    	END LOOP;
     
    	CLOSE liste_colonnes;
     
    	SET resultat = CONCAT('Base de données ', nom_bdd, ' traitée.';
     
    END
    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 !

  3. #3
    Modérateur

    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    Août 2006
    Messages
    16 799
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    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 799
    Points : 34 032
    Points
    34 032
    Billets dans le blog
    14
    Par défaut
    Je suis peut-être allé un peu vite.
    J'ai voulu utiliser ma procédure ce matin et elle n'a pas fonctionné !

    J'ai procédé à quelques corrections mais je suis bloqué sur ce message d'erreur :
    Citation Envoyé par MariaDB
    ERROR 1327: Undeclared variable: max_id : SELECT MAX(extension_id) INTO max_id FROM sage_chat.chat_extensions
    Pourtant, ma variable max_id est bien déclarée au début de la 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
    91
    92
    93
    CREATE OR REPLACE PROCEDURE test.pr_fix_auto_increment
    (
    	IN nom_bdd VARCHAR(32),
    	OUT resultat TEXT
    )
    /************************************************************************************************
    Base :			test
    Objet :			Procédure
    Auteur :		Philippe Leménager
    Version :		V 1.0 - plemenager - 2023-10-28 - Création
    Description : 	Met l'auto-incrément d'une table à la valeur max de l'id +1
    Utilise :		information_schema.SCHEMATA - Liste des BDD
    				information_schema.TABLES - Liste des tables
    				information_schema.COLUMNS - Liste des colonnes
    Historique :	
    **************************************************************************************************/
    BEGIN
    	DECLARE nom_table VARCHAR(48) DEFAULT NULL;
    	DECLARE nom_colonne VARCHAR(48) DEFAULT NULL; 
    	DECLARE nb INT DEFAULT 0;
    	DECLARE autoinc INT DEFAULT NULL;
    	DECLARE max_id INT DEFAULT NULL;
    	DECLARE data_type VARCHAR(48) DEFAULT NULL;
    	DECLARE is_nullable CHAR(3) DEFAULT NULL;
    	DECLARE commentaire VARCHAR(255) DEFAULT NULL;
    	DECLARE is_autoinc VARCHAR(48) DEFAULT NULL;
    	DECLARE requete VARCHAR(255);
    	DECLARE done BOOLEAN DEFAULT FALSE;
    	DECLARE liste_colonnes CURSOR FOR 
    		SELECT TABLE_NAME, COLUMN_NAME, DATA_TYPE, EXTRA, COLUMN_COMMENT 
    		FROM information_schema.COLUMNS 
    		WHERE TABLE_SCHEMA = nom_bdd;
    	DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
     
    	-- Vérification que la BDD existe
    	SELECT COUNT(*) INTO nb
    	FROM information_schema.SCHEMATA
    	WHERE SCHEMA_NAME = nom_bdd;
     
    	IF nb = 0 THEN 
    		SIGNAL SQLSTATE VALUE '45000'
    		SET MYSQL_ERRNO = 10027, MESSAGE_TEXT = 'Base de données inexistante';
    	ELSE
    		SET resultat = CONCAT('Traitement de la BDD ', nom_bdd, '.\n\r');
    	END IF;
     
    	-- Parcours des colonnes de la BDD
    	OPEN liste_colonnes;
     
    	read_loop: LOOP
    		FETCH liste_colonnes INTO nom_table, nom_colonne, data_type, is_autoinc, commentaire;
    		SET resultat = CONCAT(resultat, 'Colonne : ', nom_table, '.', nom_colonne, ' / Extra : ', is_autoinc);
     
    		-- Si fin de BDD alors sortie
    		IF done = TRUE THEN
    			LEAVE read_loop;
    		END IF;
     
    		-- Traitement de la colonne en auto_increment
    		IF is_autoinc = 'auto_increment' THEN
    			-- Récupération de la valeur de l'auto-incrément de la table
    			SELECT `AUTO_INCREMENT` INTO autoinc 
    			FROM information_schema.TABLES
    			WHERE TABLE_SCHEMA = nom_bdd
    				AND TABLE_NAME = nom_table;
     
    			-- Récupération de l'identifiant max de la table
    			SET requete = CONCAT('SELECT MAX(', nom_colonne, ') INTO max_id FROM ', nom_bdd, '.', nom_table);
    			PREPARE stmt FROM requete;
    			EXECUTE stmt;
    			DEALLOCATE PREPARE stmt;
     
    			-- Enregistrement des données dans le résultat
    			SET resultat = CONCAT(resultat, ' / Auto-incrément : ', autoinc, ' / Max id : ', max_id);
    			-- Si l'identifiant max est supérieur à l'auto-incrément, on change l'auto-incrément
    			IF max_id > autoinc THEN
    				SET resultat = CONCAT(resultat, ' => Correction à ', max_id + 1);
    				SET requete = CONCAT('ALTER TABLE ', nom_bdd, '.', nom_table, 
    									' MODIFY ', nom_colonne, ' ', data_type, 
    									' NOT NULL AUTO_INCREMENT COMMENT ', "'", commentaire, "', AUTO_INCREMENT = ", max_id + 1);
    				PREPARE stmt FROM requete;
    				EXECUTE stmt;
    				DEALLOCATE PREPARE stmt;
    			END IF;
    		END IF;
    		SET resultat = CONCAT(resultat, '\n\r');
    	END LOOP;
     
    	CLOSE liste_colonnes;
     
    	SET resultat = CONCAT(resultat, 'Base de données ', nom_bdd, ' traitée.');
     
    END
    Au passage, mes \n\r ne fonctionnent pas. Dans phpMyAdmin (avant que je tombe sur cette erreur), la liste des traitements dans la variable resultat s'affiche en continu sans saut de ligne. Quelle est la bonne syntaxe ?
    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 !

  4. #4
    Modérateur

    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    Août 2006
    Messages
    16 799
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    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 799
    Points : 34 032
    Points
    34 032
    Billets dans le blog
    14
    Par défaut
    Après pas mal d'essais, c'est la lecture de max_id qui pose problème.

    Je n'ai plus d'erreur avec ce code utilisant des variables @max_id et @requete au lieu de variables déclarées mais comme j'ai déjà passé ma procédure plusieurs fois, je ne sais pas si le cas de correction d'auto-incrément fonctionne car tous mes auto-incréments semblent maintenant OK.

    Il semblerait que @max_id ne puisse pas être lu une fois le DEALLOCATE PREPARE stmt effectué. Quelqu'un peu confirmer ?

    Voici mon code actuel :
    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
    91
    CREATE OR REPLACE PROCEDURE test.pr_fix_auto_increment
    (
    	IN nom_bdd VARCHAR(32),
    	OUT resultat TEXT
    )
    /************************************************************************************************
    Base :			test
    Objet :			Procédure
    Auteur :		Philippe Leménager
    Version :		V 1.0 - plemenager - 2023-10-28 - Création
    Description : 	Met l'auto-incrément d'une table à la valeur max de l'id +1
    Utilise :		information_schema.SCHEMATA - Liste des BDD
    				information_schema.TABLES - Liste des tables
    				information_schema.COLUMNS - Liste des colonnes
    Historique :	
    **************************************************************************************************/
    BEGIN
    	DECLARE nom_table VARCHAR(48) DEFAULT NULL;
    	DECLARE nom_colonne VARCHAR(48) DEFAULT NULL; 
    	DECLARE nb INT DEFAULT 0;
    	DECLARE autoinc INT DEFAULT NULL;
    	DECLARE data_type VARCHAR(48) DEFAULT NULL;
    	DECLARE is_nullable CHAR(3) DEFAULT NULL;
    	DECLARE commentaire VARCHAR(255) DEFAULT NULL;
    	DECLARE is_autoinc VARCHAR(48) DEFAULT NULL;
    	DECLARE done BOOLEAN DEFAULT FALSE;
    	DECLARE liste_colonnes CURSOR FOR 
    		SELECT TABLE_NAME, COLUMN_NAME, DATA_TYPE, EXTRA, COLUMN_COMMENT 
    		FROM information_schema.COLUMNS 
    		WHERE TABLE_SCHEMA = nom_bdd;
    	DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
     
    	-- Vérification que la BDD existe
    	SELECT COUNT(*) INTO nb
    	FROM information_schema.SCHEMATA
    	WHERE SCHEMA_NAME = nom_bdd;
     
    	IF nb = 0 THEN 
    		SIGNAL SQLSTATE VALUE '45000'
    		SET MYSQL_ERRNO = 10027, MESSAGE_TEXT = 'Base de données inexistante';
    	ELSE
    		SET resultat = CONCAT('Traitement de la BDD ', nom_bdd, '.\n\r');
    	END IF;
     
    	-- Parcours des colonnes de la BDD
    	OPEN liste_colonnes;
     
    	read_loop: LOOP
    		FETCH liste_colonnes INTO nom_table, nom_colonne, data_type, is_autoinc, commentaire;
     
    		-- Si fin de BDD alors sortie
    		IF done = TRUE THEN
    			LEAVE read_loop;
    		END IF;
     
    		-- Traitement de la colonne en auto_increment
    		IF is_autoinc = 'auto_increment' THEN
    			-- Récupération de la valeur de l'auto-incrément de la table
    			SELECT `AUTO_INCREMENT` INTO autoinc 
    			FROM information_schema.TABLES
    			WHERE TABLE_SCHEMA = nom_bdd
    				AND TABLE_NAME = nom_table;
     
    			SET resultat = CONCAT(resultat, ' Colonne : ', nom_table, '.', nom_colonne, ' / Auto-incrément : ', autoinc);
     
    			-- Récupération de l'identifiant max de la table
    			SET @max_id = NULL;
    			SET @requete = CONCAT('SELECT MAX(', nom_colonne, ') INTO @max_id FROM ', nom_bdd, '.', nom_table);
    			PREPARE stmt FROM @requete;
    			EXECUTE stmt;
    			DEALLOCATE PREPARE stmt;
     
    			-- Si l'identifiant max est supérieur à l'auto-incrément, on change l'auto-incrément
    			IF @max_id > autoinc THEN
    				SET resultat = CONCAT(resultat, ' => Correction à ', @max_id + 1);
    				SET @requete = CONCAT('ALTER TABLE ', nom_bdd, '.', nom_table, 
    									' MODIFY ', nom_colonne, ' ', data_type, 
    									' NOT NULL AUTO_INCREMENT COMMENT ', "'", commentaire, "', AUTO_INCREMENT = ", @max_id + 1);
    				PREPARE stmt FROM @requete;
    				EXECUTE stmt;
    				DEALLOCATE PREPARE stmt;
    			END IF;
    		END IF;
    		SET resultat = CONCAT(resultat, '\n\r');
    	END LOOP;
     
    	CLOSE liste_colonnes;
     
    	SET resultat = CONCAT(resultat, 'Base de données ', nom_bdd, ' traitée.');
     
    END
    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 !

  5. #5
    Expert éminent sénior Avatar de Artemus24
    Homme Profil pro
    Agent secret au service du président Ulysses S. Grant !
    Inscrit en
    Février 2011
    Messages
    6 387
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Agent secret au service du président Ulysses S. Grant !
    Secteur : Finance

    Informations forums :
    Inscription : Février 2011
    Messages : 6 387
    Points : 19 098
    Points
    19 098
    Par défaut
    Salut CinePhil.

    Ton sujet n'a pas eu beaucoup de succès.

    Il me semble que tu ne maitrises pas bien les procédures stockées de Mysql (ou MariaDB). J'ai testé celle de ton premier message, et j'ai rencontré plusieurs erreurs de syntaxe. Et la dernière n'est pas très optimisée. J'ai fait les test sur un exemple basique et je l'ai rendu plus concise.
    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
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    --------------
    START TRANSACTION
    --------------
     
    --------------
    DROP DATABASE IF EXISTS `base`
    --------------
     
    --------------
    CREATE DATABASE IF NOT EXISTS `base`
            DEFAULT CHARACTER SET `latin1`
            DEFAULT COLLATE       `latin1_general_ci`
    --------------
     
    --------------
    DROP TABLE IF EXISTS `test`
    --------------
     
    --------------
    CREATE TABLE `test`
    ( `id`   integer unsigned NOT NULL auto_increment primary key,
      `mot`  varchar(255)     NOT NULL
    ) ENGINE=InnoDB
      DEFAULT CHARSET=`latin1` COLLATE=`latin1_general_ci`
      ROW_FORMAT=COMPRESSED
    --------------
     
    --------------
    insert into `test` (`id`,`mot`) values (100,'un'),(200,'deux'),(300,'trois')
    --------------
     
    --------------
    select * from `test`
    --------------
     
    +-----+-------+
    | id  | mot   |
    +-----+-------+
    | 100 | un    |
    | 200 | deux  |
    | 300 | trois |
    +-----+-------+
     
    --------------
    drop PROCEDURE if exists `maj_increment`
    --------------
     
    --------------
    CREATE PROCEDURE `maj_increment` (IN _base varchar(255))
    DETERMINISTIC
    NO SQL
    BEGIN
            DECLARE _table   VARCHAR(255);
            DECLARE _colonne VARCHAR(255);
            DECLARE _auto    BIGINT;
            DECLARE _fin     INTEGER       DEFAULT 1;
     
            DECLARE _tab CURSOR FOR select t2.table_name,t2.column_name,t1.auto_increment from information_schema.tables as t1
                    inner join information_schema.columns as t2 on t2.table_schema = t1.table_schema and t2.table_name = t1.table_name
                    where t1.table_schema = _base and t2.extra = 'auto_increment';
     
            DECLARE CONTINUE HANDLER FOR NOT FOUND SET _fin = 0;
     
            OPEN  _tab;
            FETCH _tab INTO _table, _colonne, _auto;
     
            WHILE (_fin)
            DO
                    SET @val = NULL;
                    SET @req = CONCAT('SELECT MAX(', _colonne, ')+1 INTO @val FROM ', _base, '.', _table);
                    PREPARE stmt FROM @req;
                    EXECUTE stmt;
                    DEALLOCATE PREPARE stmt;
     
                    IF (@val > _auto) THEN
                            SET @req = CONCAT('alter table `', _base, '`.`', _table, '` auto_increment=', @val);
                            PREPARE stmt FROM @req;
                            EXECUTE stmt;
                            DEALLOCATE PREPARE stmt;
                    END IF;
     
                    SELECT _base, _table, _colonne, _auto AS Old, @val AS New;
     
                    FETCH _tab INTO _table, _colonne, _auto;
            END WHILE;
            CLOSE _tab;
    END
    --------------
     
    --------------
    call `maj_increment` ('base')
    --------------
     
    +-------+--------+----------+------+------+
    | _base | _table | _colonne | Old  | New  |
    +-------+--------+----------+------+------+
    | base  | test   | id       |  301 |  301 |
    +-------+--------+----------+------+------+
     
    --------------
    COMMIT
    --------------
     
    Appuyez sur une touche pour continuer...
    Je l'ai vérifié sous MySql 8.1.0 et ça fonctionne. Pour le test, j'ai mis le select à l'extérieur du IF ... END IF afin d'avoir un résultat, mais si tu veux juste connaitre ce qui a été modifié, il vaut mieux le déplacer dans le dernier bloc IF.

    @+
    Si vous êtes de mon aide, vous pouvez cliquer sur .
    Mon site : http://www.jcz.fr

Discussions similaires

  1. Réponses: 15
    Dernier message: 26/03/2004, 17h53
  2. Deplacer un curseur dans un RichEdit sous visual c
    Par tweek dans le forum Windows
    Réponses: 7
    Dernier message: 14/01/2004, 00h29
  3. Obtenir la position du curseur dans une Image
    Par bastoune dans le forum Composants VCL
    Réponses: 6
    Dernier message: 14/11/2003, 21h02
  4. Position du curseur dans un TMemo
    Par yokito dans le forum Composants VCL
    Réponses: 3
    Dernier message: 28/08/2003, 16h35
  5. Position du curseur dans Edit
    Par MrJéjé dans le forum C++Builder
    Réponses: 3
    Dernier message: 20/06/2002, 17h09

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