我编写了一个存储过程来复制表中的行。
这是表格
我想复制此内容,但ParentId应链接到新行。 如果我做一个简单的INSERT INTO>如上所示,从ParentId中选择将链接到ProductId 22而不是新的ProductId。
有什么建议吗?
答案 0 :(得分:1)
您的问题并不完全清楚,但如果我理解正确,您正在尝试复制构建层次结构的多个行,同时保留该层次结构。
这不能一步完成。您需要先复制行并记录新的及其匹配的旧ID。然后,您可以更新新行中的引用以指向新父项。
最简单的方法是使用MERGE语句:
CREATE TABLE dbo.tst(id INT IDENTITY(1,1), parent_id INT, other INT);
INSERT INTO dbo.tst(parent_id, other)VALUES(NULL,1);
INSERT INTO dbo.tst(parent_id, other)VALUES(1,2);
INSERT INTO dbo.tst(parent_id, other)VALUES(1,3);
INSERT INTO dbo.tst(parent_id, other)VALUES(3,4);
INSERT INTO dbo.tst(parent_id, other)VALUES(NULL,5);
INSERT INTO dbo.tst(parent_id, other)VALUES(5,6);
CREATE TABLE #tmp(old_id INT, new_id INT);
MERGE dbo.tst AS trg
USING dbo.tst AS src
ON (0=1)
WHEN NOT MATCHED
AND (src.id >= 1) --here you can put your own WHERE clause.
THEN
INSERT(parent_id, other)
VALUES(src.parent_id, src.other)
OUTPUT src.id, INSERTED.id INTO #tmp(old_id, new_id);
UPDATE trg SET
parent_id = tmp_translate.new_id
FROM dbo.tst AS trg
JOIN #tmp AS tmp_filter
ON trg.id = tmp_filter.new_id
JOIN #tmp AS tmp_translate
ON trg.parent_id = tmp_translate.old_id;
SELECT * FROM dbo.tst;
带注释的行是您可以放置自己的where子句以选择要复制的行的位置。确保实际复制所有引用的父母。如果您复制没有父项的子项,则更新将无法捕获它,并且最终将指向旧父项。
您还应该在事务中包装MERGE和UPDATE,以防止其他人读取新的和尚未完成的记录。
答案 1 :(得分:0)
您可以使用SELECT
执行此操作,只需手动指定列的顺序即可。下面是一个示例,假设您的表名为Product并且ProductId是自动递增的。请注意,SELECT
中返回的第一列是旧行的主键。
INSERT dbo.Product
SELECT
ProductId,
ArtNo,
[Description]
Specification,
Unit,
Account,
NetPrice
OhTime
FROM dbo.Product AS P
WHERE P.ParentId = 22
这有帮助吗?