1

编辑:为简单起见,已修改数据库名称

我正在尝试获取一些动态 sql,以将一些关键生产表的静态副本更新到另一个数据库(sql2008r2)中。这里的目的是允许数据(来自“静态”数据库)在一段时间内持续传播,因为我们的生产数据库几乎每天都在更新。

我正在使用 aCURSOR循环遍历包含要复制到“静态”数据库中的对象的表。这些prod表不会经常更改,但我想使它有点“面向未来”(如果可能的话!)并从INFORMATION_SCHEMA.COLUMNS每个对象中提取列名(而不是使用SELECT * FROM ...

  • 1)从我在其他帖子中读到的内容来看,EXEC()似乎是有限的,所以我相信我需要使用EXEC sp_executesql,但我很难理解这一切。

  • 2)作为额外的额外内容,如果可能的话,我还想排除特定表的某些列(“静态”数据库中的结构略有不同)

这是我到目前为止所拥有的。执行时,@colnames返回 NULL,因此@sql返回 NULL...

有人可以指导我到哪里可以找到解决方案吗?
非常感谢有关此代码的任何建议或帮助。

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

在针对information_schema. 在QUOTENAMEwhere 子句中也不需要,并且实际上会阻止匹配,因为 SQL Server 将column_name, not存储[column_name]在元数据中。最后,我将其更改为,sys.columns因为这是我们应该在 SQL Server 中派生元数据的方式。尝试:

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 回答