2013-07-27 3 views
0

У меня есть две таблицы: Table1 и Table2, которые имеют N нет. столбцов. Мне нужно обновить таблицу 1 на основе таблицы2. Я хочу обновить все столбцы таблицы 1, которые перечислены в одном столбце в таблице2.Обновление таблицы 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, которые перечислены в Table2 при сопоставлении следующего условия 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 Server, 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().

EDIT

В 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. В вашем случае, если пользователь имеет доступ к таблице2, его можно взломать, написав код 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 
Смежные вопросы