2009-12-24 5 views
0

Pourquoi ai-je l'exception suivante lorsque j'ai fait cela, quelle erreur ai-je commise? Quelle est la bonne façon d'insérer un tuple dans des tables avec des champs AUTO_INCREMENT? Que diriez-vous de supprimer, est-il possible de mettre à jour les identifiants?Utilisation de AUTO_INCREMENT dans MYSQL

string connStr = "server=localhost;user=root;database=test;port=3306;password=XXX;"; 
MySqlConnection conn = new MySqlConnection(connStr); 
try{ 
    MessageBox.Show("Hello"); 
    conn.Open(); 
    string s0 = "CREATE TABLE school.student (id INTEGER UNSIGNED NOT NULL AUTO_INCREMENT, name VARCHAR(45) NOT NULL, PRIMARY KEY (id))"; 
    string s1 = "INSERT INTO school.student VALUES (LAST_INSERT_ID(), \'john\')"; 
    string s2 = "INSERT INTO school.student VALUES (LAST_INSERT_ID(), \'mary\')"; 
    MySqlCommand cmd = new MySqlCommand(s0, conn); 
    cmd.ExecuteNonQuery();       
    cmd = new MySqlCommand(s1, conn); 
    cmd.ExecuteNonQuery();       
    cmd = new MySqlCommand(s2, conn); 
    cmd.ExecuteNonQuery(); 
    conn.Close(); 
}catch(Exception ex){ 
    TextWriter tw = new StreamWriter("C:\\test.txt"); 
    MessageBox.Show(ex.ToString()); 
    tw.WriteLine(ex.ToString()); 
} 

MySql.Data.MySqlClient.MySqlException: Duplicate entry '1' for key 'PRIMARY' 
    at MySql.Data.MySqlClient.MySqlStream.ReadPacket() 
    at MySql.Data.MySqlClient.NativeDriver.ReadResult() 
    at MySql.Data.MySqlClient.ResultSet.NextResult() 
    at MySql.Data.MySqlClient.MySqlDataReader.NextResult() 
    at MySql.Data.MySqlClient.MySqlCommand.ExecuteReader(CommandBehavior behavior) 
    at MySql.Data.MySqlClient.MySqlCommand.ExecuteNonQuery() 
    at ProjectInfo.Connect.Exec(String commandName, vsCommandExecOption executeOption, Object& varIn, Object& varOut, Boolean& handled) 

Répondre

3

Ces lignes sont le problème:

string s1 = "INSERT INTO school.student VALUES (LAST_INSERT_ID(), \'john\')"; 
string s2 = "INSERT INTO school.student VALUES (LAST_INSERT_ID(), \'mary\')"; 

Voir, la fonction LAST_INSERT_ID() renvoie la valeur de la dernière valeur AUTO_INCREMENT. Au moment de votre première insertion, aucune insertion n'a encore eu lieu et LAST_INSERT_ID() est évalué à NULL. Supposons que votre table soit vide, la ligne est insérée avec la valeur générée de 1. Lors de la deuxième insertion, LAST_INSERT_ID() sera 1 en raison de la ligne précédente insérée. Alors, cette fois-ci, il y a déjà une ligne avec 1 dans la db, et le second insert ne parvient pas à cause du double 1.

Rewrite comme ceci:

string s1 = "INSERT INTO school.student (name) VALUES (\'john\')"; 
string s2 = "INSERT INTO school.student (name) VALUES (\'mary\')"; 
+0

Thx. J'ai découvert plus tard que vous pouvez aussi faire comme ceci: chaîne s1 = "INSERT INTO projectinfo.student VALUES (NULL, \ 'john \')"; chaîne s2 = "INSERT INTO projectinfo.student VALEURS (NULL, \ 'mary \')"; – yeeen

+0

Oui, vous pouvez le faire aussi, et vous pouvez même sélectionner les enregistrements nouvellement insérés en faisant SELECT * FROM [l'onglet] WHERE [la colonne auto inc] IS NULL. Cependant, par souci de clarté et d'explicitation, je déconseille cela. C'est IMO juste étrange que vous assigniez explicitement la valeur NULL mais en fait vous obtenez une valeur nouvellement générée à la place. –

0

omettent simplement le champ qui a AUTO_INCREMENT, MySQL va prendre en charge le reste. Vous pouvez mettre à jour les ID après DELETE, mais je vous conseillerais de ne pas le faire.

0

Vous ne devriez pas essayer d'insérer une valeur dans un champ d'incrémentation automatique - comme (l'indice est dans le nom) cela sera automatiquement incrémenté par MySQL.

Questions connexes