我有一个表结构,子表中有FK列。
所以说有以下内容:
Company
-company_id
-name
Location
-location_id
-company_name
-name
Store
-store_id
-location_id
-name
Inventory
-inventory_id
-store_id
现在我想创建一个公司的副本,以及所有位置,商店和库存行。
所以说我要创建company_id = 123的副本,我必须复制所有行。
我试过了:
DECLARE @OriginalCompanyId = 123
DECALRE @companyId AS INT
INSERT Companies (name)
select c.name
from companies c
where c.companyId = @OrignalCOmpanyId
SET @companyId = SCOPE_IDENTITY()
但是这种方法不起作用,因为其他表有多行,我不能连接新插入的PK值。
我应该采取什么方法?
答案 0 :(得分:0)
我实际上一直在做一个这样做的项目。我的解决方案虽然不花哨,但到目前为止已证明有效..烦人的部分是设置过程。我对批评和改进建议持开放态度。
示例:
鉴于此架构......
CREATE TABLE Accounts (
AccountID int identity(1,1) not null,
Name varchar(500) not null
)
CREATE TABLE Users(
UserID int identity(1,1) not null,
AccountID int not null,
Name varchar(500) not null
)
CREATE TABLE NewUsers(
pUserID int not null,
UserID int not null,
AccountID int not null,
Name varchar(500)
)
这个数据
INSERT INTO NewUsers VALUES
(1,0,0,'Bob'),
(2,0,0,'Sally'),
(3,0,0,'Jeff'),
(4,0,0,'Sam')
假设每次我们“创建”我们想要创建这4个默认用户的帐户......这看起来像这样
DECLARE @AccountID int --this is scalar, so we'll use scope_identity() to grab it.
INSERT INTO Account VALUES('MyNewAccountID')
SELECT @AccountID = SCOPE_IDENTITY()
--Prepare NewUsers w/ derived accountID
UPDATE NewUsers SET AccountID = @AccountID
--Do our "application" insert
INSERT INTO Users(AccountID,Name)
SELECT AccountID,Name
FROM NewUsers
ORDER BY pUserID DESC;
--Capture inserted ID's for use in other tables (where we've derived pUserID)
WITH InsertedUsers AS(
SELECT
--use dense rank, it handles fkey mappings too
DENSE_RANK() OVER(ORDER BY UserID DESC) as pUserID,
UserID
FROM Users
)
UPDATE NewUsers SET UserID = iu.UserID
FROM NewUsers nu
JOIN InsertedUsers iu
ON iu.pUserID = nu.pUserID
SELECT TOP 100 * FROM Account ORDER BY 1 DESC
SELECT TOP 100 * FROM Users ORDER BY 1 DESC
现在,如果未来的表需要UserID进入应用程序(并且具有派生的pUserID),我们可以通过加入pUserID从NewUsers中获取它。