mySQL 中的存储过程出错
Stored procedure in mySQL going wrong
我想为我的 mySQL 服务器创建一个存储过程。
这是我的程序
CREATE PROCEDURE ClientInsertProcedure (nomClient CHAR(40), userID INT(4), tel CHAR(10), codePostal CHAR(6), noCivique CHAR(6), r CHAR(30), v CHAR(30), cred DECIMAL(6, 2))
BEGIN
INSERT INTO Entreprise(nom_entreprise, telephone, code_postal, no_civique, rue, ville, credit) VALUES(nomClient, tel, codePostal, noCivique, r, v, cred)
ON DUPLICATE KEY UPDATE telephone = tel, code_postal = codePostal, no_civique = noCivique, rue = r, ville = v, credit = cred
WHERE nom_entreprise = nomClient;
END;
它一直说我在 END;
附近的最后一行有错误
我试过 DELIMITER //
并没有任何改变。我还去了 mySQL 网站,我在那里学习了语法。我也看了Here。语法本身有什么问题还是我只是做错了?
您可能想要 nom_entreprise = nomClient
的更新。如果是这样,您需要在该列上有一个唯一的 index/constraint:
create unique index idx_ClientInsertProcedure_nomClient
on ClientInsertProcedure(nomClient);
那么,这应该有效:
CREATE PROCEDURE ClientInsertProcedure (nomClient CHAR(40), userID INT(4), tel CHAR(10), codePostal CHAR(6), noCivique CHAR(6), r CHAR(30), v CHAR(30), cred DECIMAL(6, 2))
BEGIN
INSERT INTO Entreprise(nom_entreprise, telephone, code_postal, no_civique, rue, ville, credit)
VALUES(nomClient, tel, codePostal, noCivique, r, v, cred)
ON DUPLICATE KEY UPDATE telephone = tel, code_postal = codePostal, no_civique = noCivique, rue = r, ville = v, credit = cred;
END;
作为一般建议规则,您应该使用类似 v_
的名称来命名存储过程和函数的参数,以便您可以轻松地将它们与表中的列区分开来。
你可以试试移走里面的代码,只有
CREATE PROCEDURE ClientInsertProcedure (nomClient CHAR(40), userID INT(4), tel CHAR(10), codePostal CHAR(6), noCivique CHAR(6), r CHAR(30), v CHAR(30), cred
DECIMAL(6, 2))
BEGIN
END;
如果没有错误,说明你的插入有问题
以下是我如何让代码工作:
- 我用了
DELIMITER
- 正如 Gordon Linoff 指出的那样,我不需要
WHERE
语句,因为该项目是自动选择的
If so, you need a unique index/constraint on that column
The spacing after DELIMITER is VERY important
DELIMITER //
CREATE PROCEDURE sp_ClientInsert (v_nomClient CHAR(40), v_userID INT(4), v_tel CHAR(10), v_codePostal CHAR(6), v_noCivique CHAR(6), v_rue CHAR(30), v_ville CHAR(30), v_cred DECIMAL(6, 2))
BEGIN
INSERT INTO Entreprise(nom_entreprise, telephone, code_postal, no_civique, rue, ville, credit) VALUES(v_nomClient, v_tel, v_codePostal, v_noCivique, v_rue, v_ville, v_cred)
ON DUPLICATE KEY UPDATE telephone = v_tel, code_postal = v_codePostal, no_civique = v_noCivique, rue = v_rue, ville = v_ville, credit = v_cred;
END //
DELIMETER ;
经过一些研究,DELIMITER
关键字使代码作为一个单独的块。在mySQL website上,它指定将DELIMITER
之后的字符串"//"(不带引号)替换为";"(不带引号)
The delimiter is changed to // to enable the entire definition to be passed to the server as a single statement, and then restored to ; before invoking the procedure. This enables the ; delimiter used in the procedure body to be passed through to the server rather than being interpreted by mysql itself.
这使得代码块可以作为一个整体执行。
感谢您的帮助。
编辑
这里有一个link解释INSERT INTO... ON DUPLICATE KEY UPDATE由Yu Yenken
提供
我想为我的 mySQL 服务器创建一个存储过程。
这是我的程序
CREATE PROCEDURE ClientInsertProcedure (nomClient CHAR(40), userID INT(4), tel CHAR(10), codePostal CHAR(6), noCivique CHAR(6), r CHAR(30), v CHAR(30), cred DECIMAL(6, 2))
BEGIN
INSERT INTO Entreprise(nom_entreprise, telephone, code_postal, no_civique, rue, ville, credit) VALUES(nomClient, tel, codePostal, noCivique, r, v, cred)
ON DUPLICATE KEY UPDATE telephone = tel, code_postal = codePostal, no_civique = noCivique, rue = r, ville = v, credit = cred
WHERE nom_entreprise = nomClient;
END;
它一直说我在 END;
我试过 DELIMITER //
并没有任何改变。我还去了 mySQL 网站,我在那里学习了语法。我也看了Here。语法本身有什么问题还是我只是做错了?
您可能想要 nom_entreprise = nomClient
的更新。如果是这样,您需要在该列上有一个唯一的 index/constraint:
create unique index idx_ClientInsertProcedure_nomClient
on ClientInsertProcedure(nomClient);
那么,这应该有效:
CREATE PROCEDURE ClientInsertProcedure (nomClient CHAR(40), userID INT(4), tel CHAR(10), codePostal CHAR(6), noCivique CHAR(6), r CHAR(30), v CHAR(30), cred DECIMAL(6, 2))
BEGIN
INSERT INTO Entreprise(nom_entreprise, telephone, code_postal, no_civique, rue, ville, credit)
VALUES(nomClient, tel, codePostal, noCivique, r, v, cred)
ON DUPLICATE KEY UPDATE telephone = tel, code_postal = codePostal, no_civique = noCivique, rue = r, ville = v, credit = cred;
END;
作为一般建议规则,您应该使用类似 v_
的名称来命名存储过程和函数的参数,以便您可以轻松地将它们与表中的列区分开来。
你可以试试移走里面的代码,只有
CREATE PROCEDURE ClientInsertProcedure (nomClient CHAR(40), userID INT(4), tel CHAR(10), codePostal CHAR(6), noCivique CHAR(6), r CHAR(30), v CHAR(30), cred
DECIMAL(6, 2))
BEGIN
END;
如果没有错误,说明你的插入有问题
以下是我如何让代码工作:
- 我用了
DELIMITER
- 正如 Gordon Linoff 指出的那样,我不需要
WHERE
语句,因为该项目是自动选择的If so, you need a unique index/constraint on that column
The spacing after DELIMITER is VERY important
DELIMITER // CREATE PROCEDURE sp_ClientInsert (v_nomClient CHAR(40), v_userID INT(4), v_tel CHAR(10), v_codePostal CHAR(6), v_noCivique CHAR(6), v_rue CHAR(30), v_ville CHAR(30), v_cred DECIMAL(6, 2)) BEGIN INSERT INTO Entreprise(nom_entreprise, telephone, code_postal, no_civique, rue, ville, credit) VALUES(v_nomClient, v_tel, v_codePostal, v_noCivique, v_rue, v_ville, v_cred) ON DUPLICATE KEY UPDATE telephone = v_tel, code_postal = v_codePostal, no_civique = v_noCivique, rue = v_rue, ville = v_ville, credit = v_cred; END // DELIMETER ;
经过一些研究,DELIMITER
关键字使代码作为一个单独的块。在mySQL website上,它指定将DELIMITER
之后的字符串"//"(不带引号)替换为";"(不带引号)
The delimiter is changed to // to enable the entire definition to be passed to the server as a single statement, and then restored to ; before invoking the procedure. This enables the ; delimiter used in the procedure body to be passed through to the server rather than being interpreted by mysql itself.
这使得代码块可以作为一个整体执行。
感谢您的帮助。
编辑 这里有一个link解释INSERT INTO... ON DUPLICATE KEY UPDATE由Yu Yenken
提供