2013-07-27 51 views
0

我有两个表,表1和表2,其中有N号。列。我需要根据表2更新Table1。我想更新Table1中列出的Table1中的所有列。SQL表加入更新

EG

Table1 A B C D E . . . 
      1 2 3 4 5 . . . 
      7 6 5 4 3 . . . 

    Table2 X Y Col_Nam Col_Value 
      1 2 C  8 
      1 2 D  9 
      7 6 E  10 
      7 6 C  20 
      . . .  . 
      . . .  . 

更新所有的表1中被表2中符合以下条件Table1.A时列出的列= Table2.X 和Table1.B = Table2.Y

该平台是SQL Server。 我在寻找的是一个动态的解决方案,因为我不知道我要更新的列名。表1可以有N号。需要更新的列。我使用Cursor尝试了以下内容。

DECLARE @s Varchar(MAX), @key1 VARCHAR(MAX), @key2 VARCHAR(MAX), @Cname VARCHAR(MAX), @CValue VARCHAR(MAX) 

DECLARE crs CURSOR FOR SELECT * FROM Table2 
OPEN crs; 
FETCH NEXT FROM crs inTO @key1,@key2,@Cname,@Cvalue; 
WHILE @@FETCH_STATUS = 0 
BEGIN 
set @s = 
       'Update T1 SET ' + @FieldName + ' = ''' + @FieldValue + 
     ''' from Table1 T1' + 
     ' where T1.A = ''' + @key1 + 
     ''' and T1.B = ''' + @key2 

exec(@s) 


    FETCH NEXT FROM crs inTO @key1,@key2,@Cname,@Cvalue; 

END 

CLOSE crs 
DEALLOCATE crs 

不知为什么它不工作,我想提出一个默认值,所有这些记录这些不匹配的地方条件。

任何其他解决方案或帮助将不胜感激。

+0

有一种标准的方式来做到这一点,但一个特定的平台(SQL服务器,Oracle,DB2,MySQL的等),具有更快 “捷径”。什么平台? – Hogan

+0

在相关说明:http://english.stackexchange.com/questions/68169/is-updation-a-correct-word –

+0

@JamesMohler我做了更新的标题。 – Hogan

回答

0

标准SQL的方式来做到这一点,需要相关子查询:

update table1 
    set C = coalesce((select max(col_value) 
         from Table2 t2 
         where table1.A = t2.X and table1.B = t2.Y and 
          t2.Col_Name = 'A' 
        ), C), 
     D = coalesce((select max(col_value) 
         from Table2 t2 
         where table1.A = t2.X and table1.B = t2.Y and 
          t2.Col_Name = 'D' 
        ), D) 

一些SQL引擎允许连接。下面将与MySQL的使用方法:

update table1 join 
     (select X, Y, max(case when col_name = 'C' then col_value end) as C, 
       max(case when col_name = 'D' then col_value end) as D 
     from table2 
     group by X, Y 
     ) t2 
     on t2.X = table1.A and t2.Y = table2.Y 
    set C = coalesce(t2.C, C), 
     D = coalesce(t2.D, D) 

在这两种情况下,coalesce()是为了保持当前值,当没有比赛。如果你想NULL没有匹配,那么只需删除coalesce()

编辑

在SQL Server中,用于更新/语法加入略有不同:

update table1 join 
    set C = coalesce(t2.C, C), 
     D = coalesce(t2.D, D) 
    from table1 join 
     (select X, Y, max(case when col_name = 'C' then col_value end) as C, 
       max(case when col_name = 'D' then col_value end) as D 
      from table2 
      group by X, Y 
     ) t2 
     on t2.X = table1.A and t2.Y = table2.Y; 
+0

嗨戈登,感谢您的回复,我更新了我的问题,并提供了更多详细信息,我们将不胜感激。 – user2625874

1

警告:使用任何动态SQL之前,请阅读有关SQL Injection。在你的情况下,如果用户有权访问table2,可以通过将sql代码写入col_name来破解它。

SQL FIDDLE EXAMPLE

declare @X int, @Y int, @stmt nvarchar(max), @params nvarchar(max) 

select @params = '@X int, @Y int' 

declare table_cursor cursor local fast_forward for 
    select distinct X, Y from Table2 

open table_cursor 
while 1 = 1 
begin 
    fetch table_cursor into @X, @Y 
    if @@fetch_status <> 0 break 

    select @stmt = null 
    select @stmt = 
     isnull(@stmt + ', ', '') + 
     Col_Name + ' = ' + cast(Col_Value as nvarchar(max)) 
    from Table2 
    where X = @X and Y = @Y 

    select @stmt = 'update Table1 set ' + @stmt + ' where A = @X and B = @Y' 

    exec dbo.sp_executesql 
     @stmt = @stmt, 
     @params = @params, 
     @X = @X, 
     @Y = @Y 
end 
close table_cursor 
deallocate table_cursor