从INSERT上的自动增量值创建字段

时间:2016-07-04 01:39:21

标签: php mysql

有没有办法将INSERT行放入包含AUTO_INCREMENT列的表中,并使用生成的AUTO_INCREMENT值在同一行中构建另一个字段,在单个行中查询?

我知道可以在两个操作中完成。

我们的产品使用存储为CHAR(16)的16个字符的数字帐户ID。我们希望将帐户ID存储为单个字段,因为它在我们的数据库中的许多表中被引用,但它由以下部分组成:

AccountType INT(4) UNSIGNED // never less than 1000
AccountNumber INT(10) UNSIGNED AUTO_INCREMENT PRIMARY
AccountSite INT(2) UNSIGNED

为了生成16个字符的accountID字段,将它们连接起来。 AccountType值永远不会小于1000。

我希望能够执行单个INSERT操作,如果可能的话,在同一查询中生成四个字段。

2 个答案:

答案 0 :(得分:2)

我可以用存储过程来显示它。您最终可能只需要表中的1列或2列。但我显示更多(假设文本用户友好的字符串也是如此)。这部分是微不足道的,可以在列数中缩小它。

<强>架构:

drop table if exists tX4;
create table tX4
(   AccountType INT(4) UNSIGNED not null, -- // never less than 1000
    AccountNumber INT(10) AUTO_INCREMENT PRIMARY key,
    AccountSite INT(2) UNSIGNED not null,
    col4 varchar(50) not null,
    weWantThis char(16) not null
);
-- truncate tX4; -- used for testing

存储过程:

DROP PROCEDURE IF EXISTS ins_tX4;
DELIMITER $$
CREATE PROCEDURE ins_tX4
(    p_AccountType int,
     p_AccountSite int,
     p_col4 varchar(50)
)
BEGIN
    DECLARE theAI int;
    DECLARE sConcatFix char(16);

    START TRANSACTION;
    insert tX4(AccountType,AccountSite,col4,weWantThis) values (p_AccountType,p_AccountSite,p_col4,'');
    set theAI=last_insert_id();
    set sConcatFix=concat( lpad(p_AccountType,4,'0'), lpad(theAi,10,'0'),  lpad(p_AccountSite,2,'0')  );
    update tX4 set weWantThis=sConcatFix where AccountNumber=theAI;
    COMMIT;
END$$
DELIMITER ;

<强>测试

call ins_tX4(1,2,'cat');

select * from tX4;
+-------------+---------------+-------------+------+------------------+
| AccountType | AccountNumber | AccountSite | col4 | weWantThis       |
+-------------+---------------+-------------+------+------------------+
|           1 |             1 |           2 | cat  | 0001000000000102 |
+-------------+---------------+-------------+------+------------------+

可视化片段:

0001 0000000001 02

分别是AccountType,AI,AccountSite(宽度4,10,2)。

call ins_tX4(8765,42,'Sunday');

select * from tX4;
+-------------+---------------+-------------+--------+------------------+
| AccountType | AccountNumber | AccountSite | col4   | weWantThis       |
+-------------+---------------+-------------+--------+------------------+
|           1 |             1 |           2 | cat    | 0001000000000102 |
|        8765 |             2 |          42 | Sunday | 8765000000000242 |
+-------------+---------------+-------------+--------+------------------+

weWantThis可以用作其他表格中FK的目标。

LPAD()的手册页(左边填充)。

修改

使用OUT参数发送回已分配的AI#。请注意,默认情况下参数为IN个参数。

存储过程:

DROP PROCEDURE IF EXISTS ins_tX4;
DELIMITER $$
CREATE PROCEDURE ins_tX4
(   p_AccountType int,
    p_AccountSite int,
    p_col4 varchar(50),
    OUT AI_assigned int
)
BEGIN
    DECLARE theAI int;
    DECLARE sConcatFix char(16);

    -- AI means database-assigned AUTO INCREMENT
    set AI_assigned = -1; -- assume an Error condition
    START TRANSACTION;
        insert tX4(AccountType,AccountSite,col4,weWantThis) values (p_AccountType,p_AccountSite,p_col4,'');
        set theAI=last_insert_id();
        set sConcatFix=concat( lpad(p_AccountType,4,'0'), lpad(theAi,10,'0'),  lpad(p_AccountSite,2,'0')  );
        update tX4 set weWantThis=sConcatFix where AccountNumber=theAI;
        set AI_assigned = theAI; -- the OUT parameter is set to the AI value
    COMMIT;
END$$
DELIMITER ;

从mysql环境测试:

set @var1 = -1;

call ins_tX4(22,33,'Monday',@var1);
select @var1;
-- 3

call ins_tX4(333,79,'Tuesday',@var1);
select @var1;
-- 4

从PHP环境进行测试:

由于此问题已标记为PHP,请参阅用户Matteo Tassinari的答案,如here

答案 1 :(得分:0)

这可以通过TRANSACTION完成。

START TRANSACTION; 
INSERT INTO accounts (accountType, accountSite) VALUES(1000,10); 
UPDATE accounts SET accountID = CONCAT(LPAD(accountType, 4, '0'), LPAD(accountNumber, 10, '0'), LPAD(accountSite, 2, '0')) WHERE accountNumber = LAST_INSERT_ID(); 
COMMIT;

例如可以在php中执行:

$mysqli = new mysqli(...);
$mysqli->begin_transaction();
$query = "INSERT INTO accounts (accountType, accountSite) VALUES(1000,10);"
$query .= "UPDATE accounts SET accountID = CONCAT(LPAD(accountType, 4, '0'), LPAD(accountNumber, 10, '0'), LPAD(accountSite, 2, '0')) WHERE accountNumber = LAST_INSERT_ID();"
$mysqli->query($query);
$mysqli->commit();