SQL Server中如何从其他表插入数据并利用主键插入多表?
问题解答:批量插入后获取主键并关联插入另一表
你的这种写法不可行哦,原因很简单:当你执行第一条INSERT INTO Table1(a, b) SELECT a, b FROM TempTable时,如果TempTable有多条数据,你没法直接拿到每条新插入记录的主键;就算是单条数据,你当前的写法也没有语法能直接引用刚生成的主键值。
下面分不同数据库给出可行的解决方案:
1. SQL Server 方案
可以利用OUTPUT子句捕获插入Table1时生成的主键,把这些主键临时存储,再批量插入Table2:
-- 创建临时表存储新生成的主键 CREATE TABLE #NewIds (Id INT); -- 插入Table1同时输出主键到临时表 INSERT INTO Table1(a, b) OUTPUT inserted.Id INTO #NewIds SELECT a, b FROM TempTable; -- 用临时表的主键插入Table2 INSERT INTO Table2(id, description) SELECT Id, 'Test' FROM #NewIds; -- 清理临时表 DROP TABLE #NewIds;
2. PostgreSQL 方案
PostgreSQL支持RETURNING子句,可以直接把插入的主键和要插入Table2的内容结合:
WITH InsertedTable1 AS ( INSERT INTO Table1(a, b) SELECT a, b FROM TempTable RETURNING id ) INSERT INTO Table2(id, description) SELECT id, 'Test' FROM InsertedTable1;
3. MySQL 方案
单条插入场景
如果TempTable只有一条数据,可以用876242获取刚生成的主键:
INSERT INTO Table1(a, b) SELECT a, b FROM TempTable; INSERT INTO Table2(id, description) VALUES(876242, 'Test');
批量插入场景
批量的话876242只能返回第一条记录的主键,这时候可以考虑用触发器,或者先插入Table1后通过关联TempTable的唯一字段来插入Table2:
-- 先插入Table1 INSERT INTO Table1(a, b) SELECT a, b FROM TempTable; -- 假设TempTable有唯一标识字段temp_id,关联插入Table2 INSERT INTO Table2(id, description) SELECT t1.id, 'Test' FROM Table1 t1 JOIN TempTable t2 ON t1.a = t2.a AND t1.b = t2.b;
注意:这里的关联条件要确保能唯一匹配,否则会出现重复插入的问题。
4. Oracle 方案
可以用RETURNING ... INTO结合集合,或者用CTE(Oracle 12c+支持):
-- 12c+版本用CTE方式 DECLARE TYPE id_list IS TABLE OF Table1.id%TYPE; v_ids id_list; BEGIN INSERT INTO Table1(a, b) SELECT a, b FROM TempTable RETURNING id BULK COLLECT INTO v_ids; FORALL i IN 1..v_ids.COUNT INSERT INTO Table2(id, description) VALUES(v_ids(i), 'Test'); END; / -- 或者用触发器方式,在Table1插入时自动插入Table2 CREATE OR REPLACE TRIGGER trg_table1_insert AFTER INSERT ON Table1 FOR EACH ROW BEGIN INSERT INTO Table2(id, description) VALUES(:NEW.id, 'Test'); END; /
总结一下:你原来的写法没法实现需求,需要根据你使用的数据库类型,选择对应的方法来捕获插入Table1时生成的主键,再插入Table2。
内容的提问来源于stack exchange,提问作者g00n3r
相关产品推荐
相关产品推荐

