如何编写存储过程以添加多个地址的人员记录?
如果此人只有一个地址,但我不确定如何编写存储过程来添加具有多个地址的人,这很容易。 以下是添加具有一个地址的人员的存储过程:
DELIMITER $$
CREATE PROCEDURE `log`.`spAddPerson` (
IN personID INT,
IN personName VARCHAR(100),
IN addressLine1 VARCHAR(45),
IN addressLine2 VARCHAR(45),
IN myCity VARCHAR(45),
IN myState VARCHAR(45),
IN myCountry VARCHAR(45)
)
BEGIN
DECLARE EXIT HANDLER FOR SQLEXCEPTION
BEGIN
ROLLBACK;
END;
START TRANSACTION;
INSERT INTO person VALUES(personID,personName);
-- addressid is automatically generated
INSERT INTO address(Line1, Line2,City,State,Country) VALUES
(addressLine1, addressLine2, myCity,myState, myCountry);
INSERT INTO personAddress(personID, last_insert_id());
COMMIT;
END
上面的代码工作正常。但是,我不知道如何处理具有多个地址的人而无需编写单独的存储过程。有一种简单的方法可以做到这一点吗?
答案 0 :(得分:1)
您不能将可变数量的变量传递给过程,也不能传递非标量类型。
一个可能的技巧是在调用此过程之前构建一个包含地址的临时表。临时表是预先确定的,或者将其名称作为VARCHAR
参数传递(并使用它来构建动态SQL语句)。例如:
CREATE PROCEDURE spAddPerson (tmp_table VARCHAR(10), ...)
BEGIN
...
PREPARE s AS CONCAT(
'INSERT INTO address (line1, ...) VALUES SELECT * FROM ', tmp_table
);
EXECUTE s;
...
END
-- use it like this
CREATE TEMPORARY TABLE tmp_addresses (line1 VARCHAR(255), ...);
INSERT INTO tmp_addresses VALUES ('1 Cherry Lane'), ... ;
CALL spAddPerson ('tmp_addresses', ...);
但是,我宁愿将行动分为两部分。如果地址创建失败,您真的想要完全阻止person
的创建吗?即便如此,您是否想要告知您的用户交易失败的原因(用户创建或地址创建)?
我宁愿在应用程序级别单独处理这两个例外:
issue a "START TRANSATION" try to insert a person (call stored proc 1) if it failed, rollback and notify user for each address try to insert an address (call stored proc 2) if it failed, rollback and notify user issue a "COMMIT"
答案 1 :(得分:0)
> DECLARE @LAST_INSERT_ID INT
> DECLARE @EXECUTION_OK char(1)
> SET @EXECUTION_OK = 1
>
> insert into base_table(imgPath,store,apparelType) values (imgPath,store,apparelType)
>
> SELECT @LAST_INSERT_ID = SCOPE_IDENTITY()
>
> insert into data_table(cvID,color) values (@LAST_INSERT_ID, color)
> GO
>
> If exists( Select cvID from data_table where cvID= @LAST_INSERT_ID)
> Begin
> @EXECUTION_OK = 0
> End