Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/sql-server-2008/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 2008 使用动态列名进行sql更新_Sql Server 2008_Dynamic Sql_Information Schema - Fatal编程技术网

Sql server 2008 使用动态列名进行sql更新

Sql server 2008 使用动态列名进行sql更新,sql-server-2008,dynamic-sql,information-schema,Sql Server 2008,Dynamic Sql,Information Schema,编辑:为了简单起见,对数据库名称进行了修改 我正在尝试使用一些动态sql将一些关键生产表的静态副本更新到另一个数据库(sql2008r2)。这里的目的是允许在一段时间内(从“静态”数据库)一致地传播数据,因为我们的生产数据库几乎每天都在更新 我正在使用光标在一个表中循环,该表包含要复制到“静态”数据库中的对象。 prod表不会经常更改,但我想让它成为“未来的证明”(如果可能!),并从每个对象的INFORMATION\u SCHEMA.columns中提取列名称(而不是使用SELECT*from…

编辑:为了简单起见,对数据库名称进行了修改

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

我正在使用
光标
在一个表中循环,该表包含要复制到“静态”数据库中的对象。
prod
表不会经常更改,但我想让它成为“未来的证明”(如果可能!),并从每个对象的
INFORMATION\u 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 ;
另外,我已经读过关于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 ;

非常感谢。

在对
信息\u模式的查询中,您混合了SQL和动态SQL。此外,where子句中不需要
QUOTENAME
,实际上会阻止匹配,因为SQL Server在元数据中存储
column\u name
,而不是
[column\u name]
。最后,我将把它改为
sys.columns
,因为这就是方法。尝试:

选择@colnames+=','+name
从Prod.sys.columns
其中OBJECT_NAME([OBJECT_id])=@objname
当@objname='TableXx'然后是'ExcludeCol1'ELSE'结束时,命名大小写
当@objname='TableYy'然后'ExcludeCol2'ELSE'结束时,命名CASE;
设置@colnames=STUFF(@colnames,1,1,,);

在对
信息\u模式的查询中,SQL和动态SQL混合使用。此外,where子句中不需要
QUOTENAME
,实际上会阻止匹配,因为SQL Server在元数据中存储
column\u name
,而不是
[column\u name]
。最后,我将把它改为
sys.columns
,因为这就是方法。尝试:

选择@colnames+=','+name
从Prod.sys.columns
其中OBJECT_NAME([OBJECT_id])=@objname
当@objname='TableXx'然后是'ExcludeCol1'ELSE'结束时,命名大小写
当@objname='TableYy'然后'ExcludeCol2'ELSE'结束时,命名CASE;
设置@colnames=STUFF(@colnames,1,1,,);

非常感谢Aaron,我将尝试一下。我认为INFORMATION_SCHEMA.Columns最好,但会根据您的答案修改为sys.Columns。我还知道我必须将IFs更改为CASE语句,但我不知道
的内容
并将查找此内容:)内容只是删除了前面的
-这比在查询中执行所有的
合并
连接内容要容易得多。您的答案非常有效。非常感谢。我想我把问题复杂化了。不过我个人更喜欢COALESCE——我觉得它更优雅一点,在这个例子中,它减轻了对STUFF语句的需要。不过,我可以看到其他用途的东西,所以请记住这一点。:)好吧,我想优雅是很主观的。非常感谢亚伦,我来试试。我认为INFORMATION_SCHEMA.Columns最好,但会根据您的答案修改为sys.Columns。我还知道我必须将IFs更改为CASE语句,但我不知道
的内容
并将查找此内容:)内容只是删除了前面的
-这比在查询中执行所有的
合并
连接内容要容易得多。您的答案非常有效。非常感谢。我想我把问题复杂化了。不过我个人更喜欢COALESCE——我觉得它更优雅一点,在这个例子中,它减轻了对STUFF语句的需要。不过,我可以看到其他用途的东西,所以请记住这一点。:)好吧,我想优雅是很主观的。