1

編集:データベース名は簡単にするために変更されました

いくつかの主要な本番テーブルの静的コピーを別のデータベース(sql2008r2)に更新するために、いくつかの動的SQLを配置しようとしています。ここでの目的は、本番データベースがほぼ毎日更新されるため、一定期間(「静的」データベースから)データを一貫して配布できるようにすることです。

CURSOR'static'データベースにコピーされるオブジェクトを含むテーブルをループするためにを使用しています。prodテーブルはそれほど頻繁には変更されませんが、これをある程度「将来にわたって利用できる」ようにして(可能であれば)、各オブジェクトの列名を(を使用する代わりに)抽出したいと思いINFORMATION_SCHEMA.COLUMNSますSELECT * FROM ...

  • 1)他の投稿で読んだことからEXEC()すると、制限があるように思われるので、使用する必要があると思いますがEXEC sp_executesql、頭を悩ませています。

  • 2)追加の追加として、可能であれば、特定のテーブルの一部の列も除外したいと思います(「静的」データベースでは構造がわずかに異なります)

これが私がこれまでに持っているものです。実行すると、 @colnamesNULLを返すため、NULLを@sql返します。

誰かが私に解決策を見つけることができる場所に私を導くことができますか?
このコードに関するアドバイスやヘルプは大歓迎です。

CREATE PROCEDURE sp_UpdateRefTables 
    @debug bit = 0
AS
declare @proddbname varchar(50),
    @schemaname varchar(50),
    @objname    varchar(150),
    @wherecond  varchar(150),
    @colnames   varchar(max),
    @sql        varchar(max),
    @CRLF       varchar(2)

set @wherecond = NULL;
set @CRLF = CHAR(10) + CHAR(13);

declare ObjectCursor cursor for
select  databasename,schemaname,objectname
from    Prod.dbo.ObjectsToUpdate

OPEN    ObjectCursor ;

FETCH NEXT FROM ObjectCursor
INTO @proddbname,@schemaname,@objname ;

while @@FETCH_STATUS=0
begin

if @objname = 'TableXx'
    set @wherecond = ' AND COLUMN_NAME != ''ExcludeCol1'''
if @objname = 'TableYy'
    set @wherecond = ' AND COLUMN_NAME != ''ExcludeCol2'''

--extract column names for current object
select  @colnames = coalesce(@colnames + ',', '') + QUOTENAME(column_name) 
from    Prod.INFORMATION_SCHEMA.COLUMNS
where   TABLE_NAME = + QUOTENAME(@objname,'') + isnull(@wherecond,'')

if @debug=1 PRINT '@colnames= ' + isnull(@colnames,'null')

--replace all data for @objname
--@proddbname is used as schema name in Static database
SELECT @sql = 'TRUNCATE TABLE ' + @proddbname + '.' + @objname + '; ' + @CRLF
SELECT @sql = @sql + 'INSERT INTO ' + @proddbname + '.' + @objname + ' ' + @CRLF
SELECT @sql = @sql + 'SELECT ' + @colnames + ' FROM ' + @proddbname + '.' + @schemaname + '.' + @objname + '; '

if @debug=1 PRINT '@sql= ' + isnull(@sql,'null')

EXEC sp_executesql @sql

FETCH NEXT FROM ObjectCursor
INTO    @proddbname,@schemaname,@objname ;

end
CLOSE ObjectCursor ;
DEALLOCATE ObjectCursor ;

PS私はSQLインジェクションについて読んだことがありますが、これは内部管理タスクであるため、ここでは安全だと思います!?これに関するアドバイスもいただければ幸いです。

よろしくお願いします。

4

1 に答える 1

1

に対するクエリには、SQLと動的SQLが混在していますinformation_schema。また、where句では必要ありません。SQLServerはメタデータにではなくをQUOTENAME格納するため、実際には一致をまったく防ぎます。最後に、これをに変更します。これは、 SQLServerでメタデータを取得する方法だからです。試す:column_name[column_name]sys.columns

SELECT  @colnames += ',' + name 
  FROM Prod.sys.columns
  WHERE OBJECT_NAME([object_id]) = @objname
  AND name <> CASE WHEN @objname = 'TableXx' THEN 'ExcludeCol1' ELSE '' END
  AND name <> CASE WHEN @objname = 'TableYy' THEN 'ExcludeCol2' ELSE '' END;

SET @colnames = STUFF(@colnames, 1, 1, '');
于 2012-04-17T11:47:54.250 に答える