MySQL用于更新两个表的存储过程(第2个,自动增量值从第1个开始)

时间:2015-11-12 09:56:46

标签: mysql stored-procedures

我想在我的数据库中同时更新两个表。一个表用于组,另一个表用于组成员:

CREATE TABLE IF NOT EXISTS groups (
    group_id                 INTEGER UNSIGNED AUTO_INCREMENT,
    group_name               VARCHAR(150) NOT NULL DEFAULT '',
    group_created            TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    PRIMARY KEY (group_id)
) ENGINE=InnoDB DEFAULT CHARACTER SET utf8;

CREATE TABLE IF NOT EXISTS group_members (
    group_mem_user_id        INTEGER UNSIGNED NOT NULL,
    group_mem_group_id       INTEGER UNSIGNED NOT NULL,
    group_mem_role           TINYINT DEFAULT 1,
    group_mem_created        TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    CONSTRAINT group_mem_pk PRIMARY KEY (group_mem_user_id, group_mem_group_id),
    FOREIGN KEY (group_mem_user_id) REFERENCES user (user_id),
    FOREIGN KEY (group_mem_group_id) REFERENCES groups (group_id)
) ENGINE=InnoDB DEFAULT CHARACTER SET utf8;

我想使用存储过程在group中创建一个条目,并在group_members中创建一个条目,其中包含刚刚为该组创建的ID。

我知道如何在服务器上执行此操作(我有一个java服务器,我使用Spring的JdbcTemplate来调用数据库)但我认为在存储过程中执行此操作会更好,更有效。

两个单独的查询是(我正在使用预备语句):

INSERT INTO groups (group_name) VALUES (?)

INSERT INTO group_members (group_mem_user_id, group_mem_group_id, group_mem_role) VALUES (?,?,?)

但我不确定如何将这些合并到一个存储过程中。

DELIMITER //

DROP PROCEDURE IF EXISTS create_group //
CREATE PROCEDURE create_group(
    #in/out here
)
BEGIN
    #no idea
END //

DELIMITER ;

理想情况下,我希望它返回一些描述操作是否成功的值。

1 个答案:

答案 0 :(得分:0)

I use the following procedure:

DELIMITER //

DROP PROCEDURE IF EXISTS create_group //
CREATE PROCEDURE create_group(
    IN create_group_group_name VARCHAR(150),
    IN create_group_user_id INT
)
BEGIN
    DECLARE EXIT HANDLER FOR SQLEXCEPTION, SQLWARNING
    BEGIN
        ROLLBACK;
    END;
    START TRANSACTION;
        INSERT INTO groups (group_name) VALUES (create_group_group_name);
        INSERT INTO group_members (group_mem_user_id, group_mem_group_id, group_mem_role) VALUES (create_group_user_id, LAST_INSERT_ID(), 2);
    COMMIT;
END //

DELIMITER ;

In my server I use it like:

JdbcTemplate jt = new JdbcTemplate(DB.getDataSource(DB_USER));
int i = jt.update("CALL create_group (?,?)", new Object[] {groupName, userId});
if (i != 1)
    throw new SQLException("Error creating group with name=" + groupName + " for userid=" + userId);

i == 1 if everything went well. Groups will never be created if the user is not added as a member (fixing the problem with my first iteration below).

OLD

(non-transactional, causes a problem if the second insert fails then the group is created with no members, it might work in some cases which is why I leave it here but it doesn't work for me)

The following procedure works. It does not return anything and I am just using the fact that the procedure completes without error to assume that it was all ok.

DELIMITER //

DROP PROCEDURE IF EXISTS create_group //
CREATE PROCEDURE create_group(
    IN create_group_group_name VARCHAR(150),
    IN create_group_user_id INT
)
BEGIN
    INSERT INTO groups (group_name) VALUES (create_group_group_name);
    INSERT INTO group_members (group_mem_user_id, group_mem_group_id, group_mem_role) VALUES (create_group_user_id, LAST_INSERT_ID(), 2);
END //

DELIMITER ;