我有一个旧表,其中有很多列,我想将其拆分成3个表,并具有多对多关系。
旧表没有标识列。
旧桌子:
CustomerNumber
FirstName
LastName
Address
Postal
City
....
新表格
客户:
Id
Customernumber
Firstname
Lastname
... ect
地址:
Id
Address
Postal
City
... ect
CustomerAddress
Id
CustomerId
AddressId
现在如何使用SQL将旧表散布到新表中?
我尝试过使用MERGE,但那一次最多只能处理一张桌子。一种选择是使用CURSOR,但我读到使用它或迭代是一个坏主意,但目前这是我为此找到的唯一解决方案。
declare
@CustomerId bigint,
@CustomerNumber float,
@Status int,
@Address varchar(50),
@RoadNumber int,
@LastEdited datetime,
@AddressId bigint
declare my_cursor cursor
local static read_only forward_only
for
select CustomerNumber, Address, Housenumber, Status, Date
from [db1].dbo.OldCustomer k
where
FIRMANR in (1, 40, 60, 80, 90, 120, 180, 400)
open my_cursor
fetch next from my_cursor into @CustomerNumber, @Address, @RoadNumber, @Status, @LastEdited
while @@FETCH_STATUS = 0
begin
--if the customer already exists we get the identity
if exists (select Id from [db2].dbo.Customers where CustomerNumber = @CustomerNumber)
select @CustomerId = Id from [db2].dbo.Customers where CustomerNumber = @CustomerNumber
--if the customer does not exit we need to insert and retrieve the new Identity value
else
begin
-- insert the customer
insert into [db2].dbo.Customers (CustomerNumber, [Status], LastEdited) values (@CustomerNumber, @Status, @LastEdited)
set @CustomerId = SCOPE_IDENTITY()
end
-- get address if it already exists
if exists (select Id from [db2].dbo.Addresses where Road = @Address and Roadnumber = @RoadNumber)
select @AddressId = Id from [db2].dbo.Addresses where Road = @Address and Roadnumber = @RoadNumber
else
begin
-- insert new addresses
insert into [db2].dbo.Addresses (Road,Roadnumber) values (@Address, @RoadNumber)
set @AddressId = SCOPE_IDENTITY()
end
-- insert customer => address reference if it does not exist
if not exists (select Id from [db2].dbo.CustomerAddress where CustomerId = @CustomerId and AddressId = @AddressId)
-- insert customer => address reference
insert into [db2].dbo.CustomerAddress(CustomerId,AddressId) values (@CustomerId, @AddressId)
fetch next from my_cursor into @CustomerNumber, @Address, @RoadNumber, @Status, @LastEdited
end
close my_cursor
deallocate my_cursor
答案 0 :(得分:0)
这可能是最简单的:
--populate new Address table
INSERT INTO Address(id,col1,col2...)
SELECT AddressID, col1, col2... FROM Customer
--populate new CustomerAddress table
INSERT INTO CustomerAddress(CustomerId,AddressId)
SELECT Id, AddressID FROM Customer
使用SQLS,您可以将其作为一个简单的脚本执行此操作,如果需要的话,也可以使用事务进行。不需要存储过程,游标,合并等。
不要给CustomerAddress自己的ID列; CustomerAddress的主键是CustomerId和AddressId的组合;制作复合PK,而不是单独的
Tbh,我可能没有CustomerAddress表,而在customer中只有BillingAddressId,WorkAddressId,HomeAddressId,ShippingAddressId列,但是如何管理此内容取决于您;如果您有很多地址并且类型各异,那么可以肯定地进行M:M分解,但是如果实际上您的客户最多只能有3个地址,等等,我会坚持使用一个命名列来说明该地址是什么在客户中
如果要使用CustomerAddress表,请考虑添加一列来声明地址的类型/原因