5 sql-server-2008 sql-server t-sql
我正在使用 SQL Server 2008 并且有一个问题,如果不使用许多临时表和不可靠的连接,我不知道如何解决。
表 1 包含 6 列数据,然后将其拆分为两个表。Col1 到 Col3 进入表 2,Col4 到 Col6 进入表 3。将数据放入表 2 和表 3 是容易的部分。然而,表 3 中的 T2ID 是表 2 中 ID 的外键。
性能是关键,所以我不想使用变量和/或逐行迭代数据,理想情况下,我只想要一个可以做很多事情的插入。
我曾尝试使用链接表,但表 2 和表 3 中的数据不是唯一的,这使得连接不可靠。
有什么建议?
Create Table T1 (
ID INT IDENTITY(1,1),
Col1 VARCHAR(10),
Col2 VARCHAR(10),
Col3 VARCHAR(10),
Col4 VARCHAR(10),
Col5 VARCHAR(10),
Col6 VARCHAR(10)
)
Create Table T2 (
ID INT IDENTITY(1,1),
Col1 VARCHAR(10),
Col2 VARCHAR(10),
Col3 VARCHAR(10)
)
Create Table T3 (
ID INT IDENTITY(1,1),
T2ID INT,
Col4 VARCHAR(10),
Col5 VARCHAR(10),
Col6 VARCHAR(10)
)
Run Code Online (Sandbox Code Playgroud)
我不能改变T2或T3。T1 不是临时表,我也无法更改。还有其他包也写入 T1、T2 和 T3。尽管可以在需要时在不同时间安排它们。
如果使用 MERGE 将数据插入到 中T2,则可以在T1.ID和之间生成映射表T2.ID:
DECLARE @Mapping TABLE
(
T1ID int,
T2ID int
);
MERGE INTO
dbo.T2 AS tgt
USING
dbo.T1 AS src
ON
1 = 0
WHEN NOT MATCHED THEN
INSERT ( Col1, Col2, Col3)
VALUES (src.Col1, src.Col2, src.Col3)
OUTPUT
src.ID, inserted.ID INTO @Mapping (T1ID, T2ID)
;
Run Code Online (Sandbox Code Playgroud)
与 INSERT 允许您inserted仅在 OUTPUT 子句中引用表的列不同,MERGE 语句也允许您引用源表的列。这是此解决方案的关键,因为这是将源 ID 与目标 ID 关联的方式。
一旦你有了映射表,你就可以在插入时在连接中使用它T3。INSERT ... SELECT这一次,一个平原会这样做:
INSERT INTO
dbo.T3 (T2ID, Col4, Col5, Col6)
SELECT
m.T2ID,
t.Col4,
t.Col5,
t.Col6
FROM
dbo.T1 AS t
INNER JOIN @Mapping AS m ON t.ID = m.T1ID
;
Run Code Online (Sandbox Code Playgroud)
将两个语句包装在一个事务中,以使拆分操作具有原子性。
可以在此线程中找到有关 MERGE 映射方法的讨论:
| 归档时间: |
|
| 查看次数: |
5609 次 |
| 最近记录: |