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

时间:2015-08-20 06:05:34

标签: sql sql-server database sql-server-2008 relational-database

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

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

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

table1

Id        col1         col2


table2
id        col3        table1fk

我能够将表拆分为两个表,但它在table1中创建了重复的行,并将它们映射到table2中的单行。 我想要实现的是在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);

我能做些什么来实现它?

1 个答案:

答案 0 :(得分:4)

我对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

第一个INSERT col1,col2的唯一行table1

第二个,在JOINtbl上执行table1以从table1获取FK。

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

SQL Fiddle