1

数据库模式

如何编写存储过程来添加具有多个地址的人员记录?

如果该人只有一个地址,这很容易,但我不确定如何编写存储过程来添加具有多个地址的人。这是添加具有一个地址的人员的存储过程:

 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

上面的代码工作正常。但是,如果不编写单独的存储过程,我不知道如何处理具有多个地址的人。有没有一种简单的方法可以做到这一点?

4

2 回答 2

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如果地址创建失败,您真的要完全阻止创建吗?即便如此,您难道不想告诉您的用户交易失败的原因(用户创建或地址创建)吗?

我宁愿在应用程序级别分别处理这两个异常:

    发出“开始交易”
    尝试插入一个人(调用存储过程 1)
    如果失败,回滚并通知用户
    对于每个地址
        尝试插入地址(调用存储过程 2)
        如果失败,回滚并通知用户
    发出“提交”

于 2013-08-06T00:00:03.897 回答
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
于 2015-03-20T06:54:56.953 回答