如何使用SQLServer为每列插入/更新单独的行

时间:2014-12-09 21:15:20

标签: sql-server-2008 sql-update

我尝试通过存储过程将数据从一个表导入另一个表。我需要能够进行插入和更新。我找到了插件。现在,我试图找到最优雅的方式来进行更新。

这是一个像我试图从中提取数据的表。原谅表创建脚本中的任何错误。它们只是一些例子。

CREATE TABLE [dbo].[source_table](
    [linkage_id] [int] IDENTITY(1,1) NOT NULL,
    [code] [char](6) NULL,
    [code_1] [char](6) NULL,
    [code_2] [char](6) NULL,
    [code_3] [char](6) NULL,
    [code_4] [char](6) NULL,
    [code_5] [char](6) NULL,
    [code_6] [char](6) NULL,
    [code_7] [char](6) NULL,
    [code_8] [char](6) NULL,
    [code_9] [char](6) NULL,
    [code_10] [char](6) NULL,
) ON [PRIMARY]

我需要插入这样的表:

CREATE TABLE [dbo].[destination_table](
    [id] [int] IDENTITY(1,1) NOT NULL,
    [linkage_id] [int] NULL,
    [code] [char](30) NULL
 CONSTRAINT [PK_destination_table] PRIMARY KEY CLUSTERED 
(
    [id] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON, FILLFACTOR = 90) ON [PRIMARY]
) ON [PRIMARY]

当从source_table中提取记录时,需要在源表上输入值的每个代码中将一行插入到目标表中。您最终可能会在目标表中找到这样的值:

id | linkage_id | code
______________________
1  | 501        | abc
2  | 501        | abb
3  | 501        | aba
4  | 502        | aaa
5  | 503        | aaa
6  | 503        | aab
7  | 503        | abc
8  | 503        | bba
9  | 503        | cc

然后,我可能需要使用源表中的新值更新目标表:

linkage_id | code | code_1 | code_2 | code_3 | code_4 | ...
______________________
501        | ccc  | abb    | bbb    |        |        | ...

我需要以正确的顺序更新记录。我的目标是在完成后目标表看起来像这样:

id | linkage_id | code
______________________
1  | 501        | ccc
2  | 501        | abb
3  | 501        | bbb
4  | 502        | aaa
5  | 503        | aaa
6  | 503        | aab
7  | 503        | abc
8  | 503        | bba
9  | 503        | cc

我的猜测是会有游标参与......任何人都有任何干净的想法吗?

刚刚发生的一个选择是,我可以删除所有以前的记录并重新插入,而不是尝试更新destination_table中的记录。

1 个答案:

答案 0 :(得分:1)

您可以使用UNPIVOTMERGE

-- Optional table variable to assist with processing source data into destination table. 
-- Holds the normalized form of the data in source_table
declare @p table(linkage_id int, code nchar(6))

-- UNPIVOT the data from columns into rows to be able to use MERGE
insert into @p (linkage_id, code)
select linkage_id, value
from (select linkage_id, code, code_1, code_2 from source_table) s
unpivot (
    value for [key] in (code, code_1, code_2)
) as PivotTable

-- Check out the data by eye
-- select * from @p

-- Now we can update the destination table from the normalized source values
merge destination_table as d
    using (select linkage_id, code from @p) as source (linkage_id, code)
    on d.linkage_id = source.linkage_id
when matched
    then update set d.code = source.code
when not matched
    then insert (linkage_id, code) values (source.linkage_id, source.code);