将一个表中的数据插入到另外两个主从表中,请教各位SQL语句或者存储过程。

时间:2022-01-26 05:57:08
有三个表:
表A 明细数据
ID  PName(物品名)  Num(数量)  Supplier(供应商)
1   LG显示器    10    LG科技有限公司
2   LG键盘      10    LG科技有限公司
3   音箱        10    多彩
4   机箱        10    金河田

表B 请购单表头
DNO(请购单号)  Supplier(供应商)
D001  LG科技有限公司 
D002  多彩 
D003  金河田

表C 请购单明细表 (表B和表C是主从关系,由请购单号关联)
ID  DNO(请购单号)  PName(物品名)  Num(数量)
1    D001     LG显示器     10
2    D001     LG键盘       10
3    D002     音箱         10
4    D003     机箱         10

目的:想用一SQL语句或存储过程,查询表A,然后将数据按供应商分类,插入到B和C表中。供应商编号是标识加流水号,另外写了一函数自动产生供应商编号。
目前的做法我是把A表中的数据调用到程序界面中,然后手工去添加,感觉那样做很麻烦,想用SQL在后台实现,但没什么头绪,所以请教各位能否用SQL语句来实现。

21 个解决方案

#1


首先,表设计的有问题。
--查询表A,然后将数据按供应商分类,插入到B和C表中

那么表B和表C的请购单号,从何而来?

#2


create table a(ID int, PName varchar(10), Num int,  Supplier varchar(20) )
insert into a values(1 , 'LG显示器',    10 ,   'LG科技有限公司') 
insert into a values(2 , 'LG键盘'  ,    10 ,   'LG科技有限公司') 
insert into a values(3 , '音箱'    ,    10 ,   '多彩') 
insert into a values(4 , '机箱'    ,    10 ,   '金河田')
create table b(id int identity,DNO as 'D'+right(1000+id,3),  Supplier varchar(20))
create table c(ID int, DNO varchar(10),  PName varchar(10),  Num int)
go

insert into b (Supplier) select t.Supplier from a t where ID in (select min(id) from a where Supplier = t.Supplier) order by t.id

insert into c select a.id , b.dno , a.PName , a.num from a , b where a.Supplier = b.Supplier

select * from b
/*
id          DNO     Supplier             
----------- ------- -------------------- 
1           D001    LG科技有限公司
2           D002    多彩
3           D003    金河田

(所影响的行数为 3 行)
*/

select * from c
/*
ID          DNO        PName      Num         
----------- ---------- ---------- ----------- 
1           D001       LG显示器      10
2           D001       LG键盘       10
3           D002       音箱         10
4           D003       机箱         10

(所影响的行数为 4 行)

*/

drop table a , b, c

#3


引用 1 楼 sdhdy 的回复:
首先,表设计的有问题。 
--查询表A,然后将数据按供应商分类,插入到B和C表中 

那么表B和表C的请购单号,从何而来?


表B的请购单是 D+流水号,流水号是从最后一条数据的流水号+1得到,先写表B,然后再把算出来的流水号写到表C中。

#4


引用 3 楼 bowlingljf 的回复:
引用 1 楼 sdhdy 的回复:
首先,表设计的有问题。 
--查询表A,然后将数据按供应商分类,插入到B和C表中 

那么表B和表C的请购单号,从何而来? 
 

表B的请购单是 D+流水号,流水号是从最后一条数据的流水号+1得到,先写表B,然后再把算出来的流水号写到表C中。
2楼的行不?

#5


TO dawugui :感谢你,2楼的代码测试过了,就是我想要的效果,很好用,我正在研究.

因为我的订购单号是D+年+月+4位流水号,如 D2009030001,正在修改你的代码。

#6


引用 5 楼 bowlingljf 的回复:
TO dawugui :感谢你,2楼的代码测试过了,就是我想要的效果,很好用,我正在研究. 

因为我的订购单号是D+年+月+4位流水号,如 D2009030001,正在修改你的代码。


create table a(ID int, PName varchar(10), Num int,  Supplier varchar(20) )
insert into a values(1 , 'LG显示器',    10 ,   'LG科技有限公司') 
insert into a values(2 , 'LG键盘'  ,    10 ,   'LG科技有限公司') 
insert into a values(3 , '音箱'    ,    10 ,   '多彩') 
insert into a values(4 , '机箱'    ,    10 ,   '金河田')
create table b(id int identity,DNO as 'D'+convert(varchar(6),getdate(),112) + right(10000+id,4) ,  Supplier varchar(20))
create table c(ID int, DNO varchar(11),  PName varchar(10),  Num int)
go

insert into b (Supplier) select t.Supplier from a t where ID in (select min(id) from a where Supplier = t.Supplier) order by t.id

insert into c select a.id , b.dno , a.PName , a.num from a , b where a.Supplier = b.Supplier

select * from b
/*
id          DNO             Supplier             
----------- --------------- -------------------- 
1           D2009030001     LG科技有限公司
2           D2009030002     多彩
3           D2009030003     金河田

(所影响的行数为 3 行)
*/

select * from c
/*
ID          DNO         PName      Num         
----------- ----------- ---------- ----------- 
1           D2009030001 LG显示器      10
2           D2009030001 LG键盘       10
3           D2009030002 音箱         10
4           D2009030003 机箱         10

(所影响的行数为 4 行)
*/
drop table a , b , c

#7


引用 6 楼 dawugui 的回复:
引用 5 楼 bowlingljf 的回复:
TO dawugui :感谢你,2楼的代码测试过了,就是我想要的效果,很好用,我正在研究. 

因为我的订购单号是D+年+月+4位流水号,如 D2009030001,正在修改你的代码。 
 


SQL codecreate table a(ID int, PName varchar(10), Num int,  Supplier varchar(20) )
insert into a values(1 , 'LG显示器',    10 ,   'LG科技有限公司') 
insert into a values(2 , 'LG键盘'  ,    10 ,   'LG科技有…


将函数放到字段的公式中有问题,当我改变了月份去查询数据时,编号也发生了改变,如下:

id          DNO             Supplier             
----------- --------------- -------------------- 
1           D2009050001     LG科技有限公司
2           D2009050002     多彩
3           D2009050003     金河田
7           D2009050007     LG科技有限公司
8           D2009050008     多彩
9           D2009050009     金河田

(所影响的行数为 6 行)

#8


能否用到游标循环读取,边读取边写入?  在游标内部好像可以调用函数来产生新的请购单号。

#9


那个插入B表的地方应该可以这样写的把

insert into b (Supplier)(select Supplier from a group by Supplier)

#10


引用 8 楼 bowlingljf 的回复:
能否用到游标循环读取,边读取边写入?  在游标内部好像可以调用函数来产生新的请购单号。
用游标效率低,基本上不是没办法的时候建议都别用.

#11


引用 7 楼 bowlingljf 的回复:
将函数放到字段的公式中有问题,当我改变了月份去查询数据时,编号也发生了改变,如下: 

id          DNO            Supplier            
----------- --------------- -------------------- 
1          D2009050001    LG科技有限公司 
2          D2009050002    多彩 
3          D2009050003    金河田 
7          D2009050007    LG科技有限公司 
8          D2009050008    多彩 
9          D2009050009    金河田 

(所影响的行数为 6 行) 

对,编码是根据你的时间来定.除非你自己设定好时间.

#12


引用 8 楼 bowlingljf 的回复:
能否用到游标循环读取,边读取边写入?  在游标内部好像可以调用函数来产生新的请购单号。

最好不要使用游标!

#13



编号是固定的,以后还要查询。大家都说用游标效率低,我的数据量不大的情况下应该没什么问题吧,一般A表就500条数据左右,其*应商是10个左右,当然这是一个订单的情况,如果同时有10个订单,在A表中就会有5000条数据。

#14


另外一种方法就是把A表数据读到DataGridView控件中,用循环去读取Grid控件然后写入B和C表,在界面中循环可能比游标更慢。

#15


create table a(ID int, PName varchar(10), Num int,  Supplier varchar(20) )
insert into a values(1 , 'LG显示器',    10 ,   'LG科技有限公司') 
insert into a values(2 , 'LG键盘'  ,    10 ,   'LG科技有限公司') 
insert into a values(3 , '音箱'    ,    10 ,   '多彩') 
insert into a values(4 , '机箱'    ,    10 ,   '金河田')
create table b(id int identity,DNO as 'D'+convert(varchar(6),getdate(),112) + right(10000+id,4) ,  Supplier varchar(20))
create table c(ID int, DNO varchar(11),  PName varchar(10),  Num int)
go

insert into b (Supplier) select t.Supplier from a t where ID in (select min(id) from a where Supplier = t.Supplier) order by t.id

insert into c select a.id , b.dno , a.PName , a.num from a , b where a.Supplier = b.Supplier

#16


引用 13 楼 bowlingljf 的回复:
编号是固定的,以后还要查询。大家都说用游标效率低,我的数据量不大的情况下应该没什么问题吧,一般A表就500条数据左右,其*应商是10个左右,当然这是一个订单的情况,如果同时有10个订单,在A表中就会有5000条数据。 

你开始的问题我懂了.现在的问题的不懂了.

不知道你具体要做什么?

#17


引用 16 楼 dawugui 的回复:
引用 13 楼 bowlingljf 的回复:

编号是固定的,以后还要查询。大家都说用游标效率低,我的数据量不大的情况下应该没什么问题吧,一般A表就500条数据左右,其*应商是10个左右,当然这是一个订单的情况,如果同时有10个订单,在A表中就会有5000条数据。 
 
你开始的问题我懂了.现在的问题的不懂了. 

不知道你具体要做什么?


表A是物料需求表,根据订单自动算出来的物料需求。--> 通过SQL自动产生申购单,按供应商分类,最后产生B和C表。

目前只能手工从表A中选取相同供应商的数据添加到申购单中,也就是B和C表。

我想让SQL帮我去实现自动添加到申购单中的功能。申购单有编号,这个必须要固定,以后要查询。
                

#18


很多表都有编号,规则与前面的差不多,都是字符+日期+流水号。

在批量添加数据,或者同时写入很多个表,每个表之间又有编号关联时特别麻烦,这个问题一直没有很好的解决,所以很时间只能在UI中写很多代码去解决。

dawugui 的代码很精简,如果不是因为编号的问题是可以用的。

#19


引用 12 楼 yangsnow_rain_wind 的回复:
引用 8 楼 bowlingljf 的回复:
能否用到游标循环读取,边读取边写入?  在游标内部好像可以调用函数来产生新的请购单号。 
 
最好不要使用游标!

#20


很多表都有编号,规则与前面的差不多,都是字符+日期+流水号。 

在批量添加数据,或者同时写入很多个表,每个表之间又有编号关联时特别麻烦,这个问题一直没有很好的解决,所以很时间只能在UI中写很多代码去解决。 

dawugui 的代码很精简,如果不是因为编号的问题是可以用的。


---

如果你的编号在时间上有要求,就得自己通过算法来获取对应的编号了.因不知道你具体的需求,只能帮顶了.

#21


感谢各位

#1


首先,表设计的有问题。
--查询表A,然后将数据按供应商分类,插入到B和C表中

那么表B和表C的请购单号,从何而来?

#2


create table a(ID int, PName varchar(10), Num int,  Supplier varchar(20) )
insert into a values(1 , 'LG显示器',    10 ,   'LG科技有限公司') 
insert into a values(2 , 'LG键盘'  ,    10 ,   'LG科技有限公司') 
insert into a values(3 , '音箱'    ,    10 ,   '多彩') 
insert into a values(4 , '机箱'    ,    10 ,   '金河田')
create table b(id int identity,DNO as 'D'+right(1000+id,3),  Supplier varchar(20))
create table c(ID int, DNO varchar(10),  PName varchar(10),  Num int)
go

insert into b (Supplier) select t.Supplier from a t where ID in (select min(id) from a where Supplier = t.Supplier) order by t.id

insert into c select a.id , b.dno , a.PName , a.num from a , b where a.Supplier = b.Supplier

select * from b
/*
id          DNO     Supplier             
----------- ------- -------------------- 
1           D001    LG科技有限公司
2           D002    多彩
3           D003    金河田

(所影响的行数为 3 行)
*/

select * from c
/*
ID          DNO        PName      Num         
----------- ---------- ---------- ----------- 
1           D001       LG显示器      10
2           D001       LG键盘       10
3           D002       音箱         10
4           D003       机箱         10

(所影响的行数为 4 行)

*/

drop table a , b, c

#3


引用 1 楼 sdhdy 的回复:
首先,表设计的有问题。 
--查询表A,然后将数据按供应商分类,插入到B和C表中 

那么表B和表C的请购单号,从何而来?


表B的请购单是 D+流水号,流水号是从最后一条数据的流水号+1得到,先写表B,然后再把算出来的流水号写到表C中。

#4


引用 3 楼 bowlingljf 的回复:
引用 1 楼 sdhdy 的回复:
首先,表设计的有问题。 
--查询表A,然后将数据按供应商分类,插入到B和C表中 

那么表B和表C的请购单号,从何而来? 
 

表B的请购单是 D+流水号,流水号是从最后一条数据的流水号+1得到,先写表B,然后再把算出来的流水号写到表C中。
2楼的行不?

#5


TO dawugui :感谢你,2楼的代码测试过了,就是我想要的效果,很好用,我正在研究.

因为我的订购单号是D+年+月+4位流水号,如 D2009030001,正在修改你的代码。

#6


引用 5 楼 bowlingljf 的回复:
TO dawugui :感谢你,2楼的代码测试过了,就是我想要的效果,很好用,我正在研究. 

因为我的订购单号是D+年+月+4位流水号,如 D2009030001,正在修改你的代码。


create table a(ID int, PName varchar(10), Num int,  Supplier varchar(20) )
insert into a values(1 , 'LG显示器',    10 ,   'LG科技有限公司') 
insert into a values(2 , 'LG键盘'  ,    10 ,   'LG科技有限公司') 
insert into a values(3 , '音箱'    ,    10 ,   '多彩') 
insert into a values(4 , '机箱'    ,    10 ,   '金河田')
create table b(id int identity,DNO as 'D'+convert(varchar(6),getdate(),112) + right(10000+id,4) ,  Supplier varchar(20))
create table c(ID int, DNO varchar(11),  PName varchar(10),  Num int)
go

insert into b (Supplier) select t.Supplier from a t where ID in (select min(id) from a where Supplier = t.Supplier) order by t.id

insert into c select a.id , b.dno , a.PName , a.num from a , b where a.Supplier = b.Supplier

select * from b
/*
id          DNO             Supplier             
----------- --------------- -------------------- 
1           D2009030001     LG科技有限公司
2           D2009030002     多彩
3           D2009030003     金河田

(所影响的行数为 3 行)
*/

select * from c
/*
ID          DNO         PName      Num         
----------- ----------- ---------- ----------- 
1           D2009030001 LG显示器      10
2           D2009030001 LG键盘       10
3           D2009030002 音箱         10
4           D2009030003 机箱         10

(所影响的行数为 4 行)
*/
drop table a , b , c

#7


引用 6 楼 dawugui 的回复:
引用 5 楼 bowlingljf 的回复:
TO dawugui :感谢你,2楼的代码测试过了,就是我想要的效果,很好用,我正在研究. 

因为我的订购单号是D+年+月+4位流水号,如 D2009030001,正在修改你的代码。 
 


SQL codecreate table a(ID int, PName varchar(10), Num int,  Supplier varchar(20) )
insert into a values(1 , 'LG显示器',    10 ,   'LG科技有限公司') 
insert into a values(2 , 'LG键盘'  ,    10 ,   'LG科技有…


将函数放到字段的公式中有问题,当我改变了月份去查询数据时,编号也发生了改变,如下:

id          DNO             Supplier             
----------- --------------- -------------------- 
1           D2009050001     LG科技有限公司
2           D2009050002     多彩
3           D2009050003     金河田
7           D2009050007     LG科技有限公司
8           D2009050008     多彩
9           D2009050009     金河田

(所影响的行数为 6 行)

#8


能否用到游标循环读取,边读取边写入?  在游标内部好像可以调用函数来产生新的请购单号。

#9


那个插入B表的地方应该可以这样写的把

insert into b (Supplier)(select Supplier from a group by Supplier)

#10


引用 8 楼 bowlingljf 的回复:
能否用到游标循环读取,边读取边写入?  在游标内部好像可以调用函数来产生新的请购单号。
用游标效率低,基本上不是没办法的时候建议都别用.

#11


引用 7 楼 bowlingljf 的回复:
将函数放到字段的公式中有问题,当我改变了月份去查询数据时,编号也发生了改变,如下: 

id          DNO            Supplier            
----------- --------------- -------------------- 
1          D2009050001    LG科技有限公司 
2          D2009050002    多彩 
3          D2009050003    金河田 
7          D2009050007    LG科技有限公司 
8          D2009050008    多彩 
9          D2009050009    金河田 

(所影响的行数为 6 行) 

对,编码是根据你的时间来定.除非你自己设定好时间.

#12


引用 8 楼 bowlingljf 的回复:
能否用到游标循环读取,边读取边写入?  在游标内部好像可以调用函数来产生新的请购单号。

最好不要使用游标!

#13



编号是固定的,以后还要查询。大家都说用游标效率低,我的数据量不大的情况下应该没什么问题吧,一般A表就500条数据左右,其*应商是10个左右,当然这是一个订单的情况,如果同时有10个订单,在A表中就会有5000条数据。

#14


另外一种方法就是把A表数据读到DataGridView控件中,用循环去读取Grid控件然后写入B和C表,在界面中循环可能比游标更慢。

#15


create table a(ID int, PName varchar(10), Num int,  Supplier varchar(20) )
insert into a values(1 , 'LG显示器',    10 ,   'LG科技有限公司') 
insert into a values(2 , 'LG键盘'  ,    10 ,   'LG科技有限公司') 
insert into a values(3 , '音箱'    ,    10 ,   '多彩') 
insert into a values(4 , '机箱'    ,    10 ,   '金河田')
create table b(id int identity,DNO as 'D'+convert(varchar(6),getdate(),112) + right(10000+id,4) ,  Supplier varchar(20))
create table c(ID int, DNO varchar(11),  PName varchar(10),  Num int)
go

insert into b (Supplier) select t.Supplier from a t where ID in (select min(id) from a where Supplier = t.Supplier) order by t.id

insert into c select a.id , b.dno , a.PName , a.num from a , b where a.Supplier = b.Supplier

#16


引用 13 楼 bowlingljf 的回复:
编号是固定的,以后还要查询。大家都说用游标效率低,我的数据量不大的情况下应该没什么问题吧,一般A表就500条数据左右,其*应商是10个左右,当然这是一个订单的情况,如果同时有10个订单,在A表中就会有5000条数据。 

你开始的问题我懂了.现在的问题的不懂了.

不知道你具体要做什么?

#17


引用 16 楼 dawugui 的回复:
引用 13 楼 bowlingljf 的回复:

编号是固定的,以后还要查询。大家都说用游标效率低,我的数据量不大的情况下应该没什么问题吧,一般A表就500条数据左右,其*应商是10个左右,当然这是一个订单的情况,如果同时有10个订单,在A表中就会有5000条数据。 
 
你开始的问题我懂了.现在的问题的不懂了. 

不知道你具体要做什么?


表A是物料需求表,根据订单自动算出来的物料需求。--> 通过SQL自动产生申购单,按供应商分类,最后产生B和C表。

目前只能手工从表A中选取相同供应商的数据添加到申购单中,也就是B和C表。

我想让SQL帮我去实现自动添加到申购单中的功能。申购单有编号,这个必须要固定,以后要查询。
                

#18


很多表都有编号,规则与前面的差不多,都是字符+日期+流水号。

在批量添加数据,或者同时写入很多个表,每个表之间又有编号关联时特别麻烦,这个问题一直没有很好的解决,所以很时间只能在UI中写很多代码去解决。

dawugui 的代码很精简,如果不是因为编号的问题是可以用的。

#19


引用 12 楼 yangsnow_rain_wind 的回复:
引用 8 楼 bowlingljf 的回复:
能否用到游标循环读取,边读取边写入?  在游标内部好像可以调用函数来产生新的请购单号。 
 
最好不要使用游标!

#20


很多表都有编号,规则与前面的差不多,都是字符+日期+流水号。 

在批量添加数据,或者同时写入很多个表,每个表之间又有编号关联时特别麻烦,这个问题一直没有很好的解决,所以很时间只能在UI中写很多代码去解决。 

dawugui 的代码很精简,如果不是因为编号的问题是可以用的。


---

如果你的编号在时间上有要求,就得自己通过算法来获取对应的编号了.因不知道你具体的需求,只能帮顶了.

#21


感谢各位