Problème de curseur Mysql?
J'ai écrit une procédure stockée qui voyagera le dossier d'une table et l'insérera dans 2-3 tables différentes en utilisant des instructions d'insertion.
Le problème est que je vérifie si l'enregistrement n'existe pas dans la table1, puis j'insère l'enregistrement de tentable dans la table1, la table2 séquentiellement, mais la condition a un problème, je ne sais pas si cela va toujours dans une autre partie.
L'échantillon de code est le suivant:
CREATE PROCEDURE `insertData`(In clientNo INT,In usedID INT)
BEGIN
declare mame varchar(100);
declare address varchar(100);
declare city varchar(50);
declare IdentityNO1 varchar(20)
declare cur1 cursor for select * from temptable;
declare continue handler for not found set done=1;
SET @clientNo = clientNO;
SET @userID = userID;
set done = 0;
open cur1;
igmLoop: loop
fetch cur1 into Name,Address,City,IdentityNO1,clientNo;
if done = 1 then leave igmLoop; end if;
//If no record exists in some records table1,table2.
IF ( (SELECT COUNT(*) FROM table1
WHERE IndentityNo=IdentityNo1
AND clientNo=@clientNo) < = 0)
INSERT INTO table1 (Name,IdentityNO) VALUES (name,IdentityNO1);
INSERT INTO table2 (Address,City) VALUES(address,city);
ELSE
INSERT INTO tblexceptional(Name,Address,City,IdentityNo)
VALUES(name,address,city,IdentityNo1);
end loop igmLoop;
close cur1;
END
Il n'y a ni THEN
ni END IF
mots-clés, la procédure ne peut pas être compilée.
Vérifiez ce lien pour la syntaxe appropriée de l'instruction IF
: http://dev.mysql.com/doc/refman/5.7/en/if.html
Utilisez l'opérateur EXIST
au lieu de (SELECT count(*)... ) <=0
,
lisez ce lien pour en connaître la raison: http://sqlblog.com/blogs/andrew_kelly/archive/2007/12/15/exists-vs-count-the-battle-never-ends .aspx
IF EXISTS(
SELECT null FROM table1
WHERE IndentityNo=IdentityNo1
AND clientNo=@clientNo
)
THEN
INSERT INTO table1 (Name,IdentityNO) VALUES (name,IdentityNO1);
INSERT INTO table2 (Address,City) VALUES(address,city);
ELSE
INSERT INTO tblexceptional(Name,Address,City,IdentityNo)
VALUES(name,address,city,IdentityNo1);
END IF;
Je recommande d'utiliser certains préfixes pour les arguments de procédure et les noms de variable pour éviter toute ambiguïté, par exemple, utilisez p_
pour les paramètres et v_
pour les variables. Il est difficile de deviner, en regardant ce code, quel nom est un nom de colonne, une variable ou un paramètre de procédure. Cela peut entraîner des erreurs et des erreurs.
Évitez d'utiliser SELECT *
- ce code échouera si quelqu'un change la structure de la table. Liste explicitement les colonnes requises dans la déclaration du curseur:
declare cur1 cursor for
select name,Address,City,IdentityNO,clientNo
from temptable;
La procédure corrigée pourrait ressembler à ceci:
CREATE PROCEDURE `insertData`(In p_clientNo INT,In p_usedID INT)
BEGIN
declare v_name varchar(100);
declare v_address varchar(100);
declare v_city varchar(50);
declare v_IdentityNO varchar(20)
declare v_clientNo int
declare cur1 cursor for
select name,Address,City,IdentityNO,clientNo
from temptable;
declare continue handler for not found set done=1;
set done = 0;
open cur1;
igmLoop: loop
fetch cur1 into v_name,v_Address,v_City,v_IdentityNO,v_clientNo;
if done = 1 then leave igmLoop; end if;
//If no record exists in some records table1,table2.
IF EXISTS( SELECT 1 FROM table1
WHERE IndentityNo = v_IdentityNo
AND clientNo = v_clientNo)
INSERT INTO table1 (Name,IdentityNO) VALUES (v_name,v_IdentityNO);
INSERT INTO table2 (Address,City) VALUES(v_address,v_city);
ELSE
INSERT INTO tblexceptional(Name,Address,City,IdentityNo)
VALUES(v_name,v_address,v_city,v_IdentityNo);
END IF;
end loop igmLoop;
close cur1;
END