Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 规范化数据库时从单个表插入多个表_Sql_Sql Server_Database_Sql Server 2008_Relational Database - Fatal编程技术网

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

Sql 规范化数据库时从单个表插入多个表,sql,sql-server,database,sql-server-2008,relational-database,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的主键到外键关系。这就是它的样子 table

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

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

我使用的查询是

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
第一个,
INSERT
s将
col1、col2
的唯一行插入
table1

第二个,在
tbl
table1
上执行
JOIN
,以从
table1
获取FK

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


我对
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
s将
col1、col2
的唯一行插入
table1

第二个,在
tbl
table1
上执行
JOIN
,以从
table1
获取FK

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


是的,我同意。保持简单,而不是使用合并。你不需要它提供的UPDATE/DELETE功能,所以两个INSERT语句就可以用最少的复杂度完成这个任务……是的,它看起来比我的方法简单得多,也更容易理解。非常感谢你的帮助。作为一名应用程序开发人员,它很难深入研究数据库。没问题。很高兴我能帮忙。是的,我同意。保持简单,而不是使用合并。你不需要它提供的UPDATE/DELETE功能,所以两个INSERT语句就可以用最少的复杂度完成这个任务……是的,它看起来比我的方法简单得多,也更容易理解。非常感谢你的帮助。作为一名应用程序开发人员,它很难深入研究数据库。没问题。很高兴我能帮忙。