动态临时表

时间:2012-12-01 04:28:42

标签: sql

我必须在sql server中创建一个动态临时表,基于列列表,例如,我有一个表ListOfColumns,里面有许多列的名称,引用一个真实的表

ListOfColumns
ColumnNameA
ColumnNameB
ColumnNameC

我创建了一个函数,以这种格式获取包含所有这些列的字符串:

"ColumnNameA, ColumnNameB, ColumnNameC"

现在我需要根据名为Report的实际表中的列创建临时表。我可以有更多或更少的列(它是一个动态报告列生成器)

我需要做一个动态SQL,我没有每列的数据类型,我想用动态sql创建一个临时表,并继承我的Report表的数据类型。有没有办法做到这一点?

顺便说一句......我不想使用全局变量。 谢谢。

2 个答案:

答案 0 :(得分:0)

例如,如果您的报告表看起来像这样:

create table Report (
  ColumnNameA varchar(4),
  ColumnNameB integer,
  ColumnNameC integer,
  ColumnNameD varchar(8),
  ColumnNameE bit,
  ColumnNameF integer
 );

您可以创建以下过程:

create proc copy_table @col_names varchar(128)
as
DECLARE @SQLQuery AS NVARCHAR(500)
SET @SQLQuery = 'SELECT ' + @col_names + ' into ReportTemp from Report where 1 = 0'
EXEC(@SQLQuery);

并使用您拥有的逗号分隔列字符串调用它,如下所示:

exec copy_table @col_names = 'ColumnNameA, ColumnNameB, ColumnNameC'

您应该使用正确的列类型创建表。要测试它,请插入一行然后查询它。

insert into ReportTemp values ('abc', 1, 2 );
select * from ReportTemp;

要查看此操作,请查看此sql fiddle

请注意,这将结转约束,索引等 - 只是列名和类型。

答案 1 :(得分:0)

您无法创建动态临时表。

原因是临时表与SQL会话相关联。执行动态SQL时,它会创建一个在会话结束时终止的新会话。因此,该表在exec期间创建。然后当控制移回调用过程时,它会被丢弃(或超出上下文)。

以下是一些解决方法,您可能不喜欢这些:

  1. 创建一个带有规范前缀的表,例如" _"代表工作台。然后将此表放在存储过程中,并捕获异常,以便在几乎所有情况下都将其删除。
  2. 创建一个包含所有可能列值的临时表。
  3. 创建自己的"临时"这种工作表的数据库。
  4. 使用通用列名称,并将这些通用列的对应关系保留在其他位置的列中。