1

私たちが取り組んでいるさまざまな環境からエンティティ (30 以上のテーブルにまたがる) を複製するストアド プロシージャの膨大なセットがあります: Dev/Integration/PreProd/Prod

アイデアは、DB 構造がプラットフォームから別のプラットフォームに変わることがあります。一般に、1 ~ 2 列を新しいテーブルに移動したり、新しいテーブルを構造に追加したりするなど、小さな変更を行っています。

このレプリケーションの複雑さを考慮して、DB 構造に関連する違いに関係なく、すべての環境でこれらの手順の単一バージョンを使用して、任意の環境から別の環境へのレプリケーションが可能になるようにしたいと考えています。たとえば、列がsrcdest => に存在する場合はそのロジックを実行し、そうでない場合は他のロジックを実行します。

アイデアは、コードが列の存在をチェックし、そのコードの分岐が実行されない場合でも、ストアド プロシージャで存在しない列を使用できないということです。

最適な選択肢は でコードを書くことsp_executesqlでしたが、コードは非常に複雑になります。構造の変更がすべての環境で調整されたら、コードの一部を破棄する必要があることを考慮すると、あまりにも複雑になります。

4

1 に答える 1

2

必要なすべてのテーブルと将来のすべてのテーブルに識別可能な命名規則があることを確認して、sys.all_objects および sys.all_columns テーブルを使用してレプリケートするテーブル/列をクエリできるようにします。この例では、ソース DB 名を @SourceDB パラメーターを介してストアド プロシージャに渡し、ソース/宛先テーブル/列名が交差する場所に挿入を実行できます。現在の DB であると推定されるため、宛先 DB は指定されていません。

-- get intersecting table/column names from @SourceDB
-- and Destination (Current) DB
declare @sql nvarchar(max)
set @sql = 'select o.name,c.name
    from ' + @SourceDB + '.sys.all_objects o
        inner join ' + @SourceDB + '.sys.all_columns c
            on c.object_id = o.object_id
    where o.type = ''U''
    and o.name like ''SomeStringToIdentifyYourTables%''
    intersect
    select o.name,c.name
    from sys.all_objects o
        inner join sys.all_columns c
            on c.object_id = o.object_id
    where o.type = ''U''
    and o.name like ''SomeStringToIdentifyYourTables%'''   
declare @TblColNames table(TblName nvarchar(200),ColName nvarchar(200))
insert into @TblColNames
exec(@sql)

-- insert data from Source DB to Destination (Current) DB
-- where Table/Column Names Intersect
declare @sql nvarchar(max)
set @sql = ''
select @sql = @sql + 'insert into ' +
    o.name + ' (' + replace((
                    select c.name +
                        case row_number() over(order by c.name desc)
                        when 1 then '' else '||' end
                    from @TblColNames c
                    where c.TblName = o.TblName
                    order by c.name asc
                    for xml path('')),'||',',') + ')
    select ' + replace((
                    select c.name +
                        case row_number() over(order by c.name desc)
                        when 1 then '' else '||' end
                    from @TblColNames c
                    where c.TblName = o.TblName
                    order by c.name asc
                    for xml path('')),'||',',') + '
    from ' + @SourceDB + '..' + o.name + '
'
from @TblColNames o
exec(@sql)
于 2014-04-01T00:21:38.087 に答える