在规范化数据库时从单个 Table 插入多个表

Inserting From a single Table into multiple tables while Normalizing the database

好的,所以我有一个 table 包含以下列

col1        col2       col3
a            a          1
a            a          2
a            b          3
a            b          4
a            b          5

所以我必须将上面提到的 table 拆分为多个 table,同时将 col1 和 col2 保持在单独的 table 中,并将主键与外键关系与 col3 保持在另一个 table。这是它的样子。

table1

Id        col1         col2


table2
id        col3        table1fk

我能够将 table 拆分为两个 table,但它在 table1 中创建了重复行并将它们映射到 table 中的单行2. 我想要实现的是在 table1 中创建一个不同的行并将它们映射到 table2 中的多个不同的行。

我使用的查询是。

Merge Into table1 As c
Using oldtable ON 1=0

When Not Matched By Target Then
Insert(col1,col2) Values(val1,val2)
Output Inserted.Id,oldtable.val3
Into table2(fktable1,col3);

我可以做些什么来实现它?

我对 MERGE 不是很熟悉,所以我提出了一个使用两个 INSERT 语句的替代解决方案:

BEGIN TRY
    BEGIN TRANSACTION

    INSERT INTO table1(col1, col2)
        SELECT DISTINCT col1, col2 FROM tbl

    INSERT INTO table2(col3, table1fk)
        SELECT
            t.col3,
            t1.Id
        FROM tbl t
        INNER JOIN table1 t1
            ON t1.col1 = t.col1
            AND t1.col2 = t.col2

    COMMIT TRANSACTION
END TRY

BEGIN CATCH
    IF (@@TRANCOUNT > 0) BEGIN
        ROLLBACK TRANSACTION
    END
    DECLARE
            @ErrorNumber    INT,
            @ErrorMessage   NVARCHAR(4000),
            @ErrorState     INT,
            @ErrorSeverity  INT,
            @ErrorLine      INT

    SELECT
        @ErrorNumber    =   ERROR_NUMBER(),
        @ErrorSeverity  =   ERROR_SEVERITY(),
        @ErrorState     =   ERROR_STATE(),
        @ErrorLine      =   ERROR_LINE(),
        @ErrorMessage   =   ERROR_MESSAGE()

    RAISERROR(@ErrorMessage, @ErrorSeverity, @ErrorState)
    PRINT 'Error detected, transaction rolled back.'
END CATCH

第一个,col1,col2INSERT 唯一行变成 table1

第二个,在 tbltable1 上执行 JOIN 以从 table1 获得 FK。

这两个INSERT语句只能在一个事务下。

SQL Fiddle