我需要按照指定的顺序从表值插入中返回行。
我可以使用OUTPUT INTO
DECLARE @generated1 TABLE ([Id] varbinary(8), [OwnerId] [int]);
INSERT INTO [Blog] ([OwnerId])
OUTPUT INSERTED.*
INTO @generated1
VALUES ('1'),
('2'),
('1'),
('2'),
('2'),
('3'),
('3'),
('3'),
('3');
SELECT * FROM @generated1;
这通常有效并返回
Id OwnerId
===========================
0x418B6EC7C6AC864D 1
0x6D0B89E56AB3EC48 2
0xE1B86C6A3C64AB42 1
0x51B8D9D1FCDE1647 2
0xB5AD578020CBCE4C 2
0x56CD3FF610080841 3
0x1D0D5B370A732C43 3
0x0B71CDB5CE6E0445 3
0x6A8AE3A2BD19924E 3
但是如果在OwnerId上定义了FK并且插入了超过125行,则插入它们的顺序与指定的顺序不同。
答案 0 :(得分:2)
可以实现的一种方法是向要插入的每一行添加一个顺序值,将generated
表与指定的值连接起来,并按添加的顺序值排序:
DECLARE @inserted1 TABLE ([Order] [int], [OwnerId] [int]);
INSERT INTO @inserted1
VALUES ('1', '1'),
('2', '2'),
('3', '1'),
('4', '3'),
('5', '2'),
('6', '3'),
('7', '3'),
('8', '2'),
('9', '3');
DECLARE @generated1 TABLE ([Id] varbinary(8), [OwnerId] [int]);
INSERT INTO [Blog] ([OwnerId])
OUTPUT INSERTED.[Id], INSERTED.[OwnerId]
INTO @generated1
SELECT [OwnerId] FROM @inserted1;
SELECT *
FROM (SELECT [g].[Id], [g].[OwnerId], [i].[Order]
FROM @generated1 [g]
INNER JOIN @inserted1 [i]
ON [g].[OwnerId] = [i].[OwnerId]) t
ORDER BY [Order];
但由于OwnerId
不唯一,因此会产生比插入更多的行:
Id OwnerId Order
0x2557DCF354F9CD4E 1 1
0x3A265F70A2018249 1 1
0xA21503CD2F928144 2 2
0xE8C593480FCEAF41 2 2
0xC3E3C969BEA87641 2 2
0x2557DCF354F9CD4E 1 3
0x3A265F70A2018249 1 3
0x3F7EBD8EE702B44B 3 4
0xA3F09A3A612ACF41 3 4
0xA45D8F6FF779A74C 3 4
0x7BA9521290232D43 3 4
0xA21503CD2F928144 2 5
0xE8C593480FCEAF41 2 5
0xC3E3C969BEA87641 2 5
0x3F7EBD8EE702B44B 3 6
0xA3F09A3A612ACF41 3 6
0xA45D8F6FF779A74C 3 6
0x7BA9521290232D43 3 6
0x3F7EBD8EE702B44B 3 7
0xA3F09A3A612ACF41 3 7
0xA45D8F6FF779A74C 3 7
0x7BA9521290232D43 3 7
0xA21503CD2F928144 2 8
0xE8C593480FCEAF41 2 8
0xC3E3C969BEA87641 2 8
0x3F7EBD8EE702B44B 3 9
0xA3F09A3A612ACF41 3 9
0xA45D8F6FF779A74C 3 9
0x7BA9521290232D43 3 9
Id
和Order
列中仍然只有9个唯一值,但它们的组合方式无关紧要,因为标识该行的唯一值是OwnerId
。诀窍是从结果中删除行,只返回9行,Id
和Order
中的值是唯一的。对两个列进行分区提供了一种确定性地对组合进行排序的方法:
SELECT *
FROM (SELECT [g].[Id], [g].[OwnerId], [i].[Order],
ROW_NUMBER() OVER (PARTITION BY [g].[Id] ORDER BY [i].[Order]) AS RowNumber,
ROW_NUMBER() OVER (PARTITION BY [i].[Order] ORDER BY [g].[Id]) AS RowNumber2
FROM @generated1 [g]
INNER JOIN @inserted1 [i]
ON [g].[OwnerId] = [i].[OwnerId]) t
WHERE RowNumber = RowNumber2
ORDER BY [Order];
这将按预期顺序返回行:
Id OwnerId Order RowNumber RowNumber2
======================================================
0x2A51E4E35D2FA040 1 1 1 1
0x787E303904EC764C 2 2 1 1
0x778CE142E9760248 1 3 2 2
0xC056C57F1729E643 3 4 1 1
0xC0706FF6A8890E40 2 5 2 2
0x0E2058F3F142DF42 3 6 2 2
0x4690B24BE196374B 3 7 3 3
0x9F70CA6011ECD449 2 8 3 3
0xF35D87D1BDB2C34F 3 9 4 4