0

Table1 と Table2 の 2 つのテーブルがあり、N 番号がありません。列の。Table2 に基づいて Table1 を更新する必要があります。Table2 の 1 つの列にリストされている Table1 のすべての列を更新したいと考えています。

例えば

    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
             . .    .       .
             . .    .       .

次の条件 Table1.A = Table2.X および Table1.B = Table2.Y に一致する場合、Table2 にリストされている Table1 のすべての列を更新します。

プラットフォームは SQL Server です。私が探しているのは、更新しようとしている列名がわからないため、動的なソリューションです。Table1 には 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

どういうわけか機能していないので、where 条件に一致しないすべてのレコードにデフォルト値を設定したいと考えています。

他の解決策や助けをいただければ幸いです。

4

2 に答える 2

1

警告: 動的 SQL を使用する前に、 SQL インジェクションについて読んでください。あなたの場合、ユーザーがtable2にアクセスできる場合、SQLコードをcol_nameに書き込むことでハッキングされる可能性があります.

SQL フィドルの例

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
于 2013-07-28T19:16:14.037 に答える
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;
于 2013-07-27T16:20:32.093 に答える