如何在SQL查询的FROM区域中使用动态表名?

时间:2011-11-16 22:03:41

标签: sql sql-server-2005 sql-server-2008 partitioning dynamic-sql

原始问题: 我正在使用一个每月生成一个新表的数据库,并将YYYY_MM附加到新表名。我需要编写一个查询,查看当前月份的表格。除了日期函数,我发现我无法构建表名!

示例表名称为DOCUMENTS_2011_10

我尝试使用这样的基本脚本,但它在语法问题上失败了:

SELECT * FROM ('DOCUMENTS_'+'2011_10')

有什么建议吗?

附加信息: 这些表由我们的企业门户应用程序(Oracle WebCenter Interaction)生成。重新设计此应用程序以更改其处理数据的方式是我无法控制的。

我被要求提取一份报告,显示这些表中每月生成的关键数据。

我的方法是创建一个SQL Reporting Service订阅,每月以Excel格式通过电子邮件发送数据 我需要有关此查询的帮助才能将其插入到报告服务中,因此我不必每个月都要使用查询来更改表名。

由于报告服务将每月触发并生成报告,因此不需要存档数据或任何类型的临时功能。

使用动态SQL我能够设置表名,不幸的是,当我尝试添加其余的查询时,它会抱怨字符限制问题。知道怎么解决这个问题吗?

这让我得到了正确的表格:

Declare @tblName Varchar(400)
Declare @SQL Varchar(500)

Set @tblName = 
'analyticsdbuser.ASFACT_DOCUMENTVIEWS_'
+ CONVERT(VARCHAR,DATEPART(yyyy,GETDATE())) 
+ '_'
+ CONVERT(VARCHAR, RIGHT('0' + RTRIM(MONTH(GETDATE())-1), 2));

SET @SQL = 'SELECT * FROM ' + @Tblname;
Exec(@SQL)

这是另一个需要执行但不适合@SQL的查询:

SELECT   t2.ID,
         t2.USERID,
         t3.NAME,
         t2.DOCUMENTID,
         t1.NAME AS DOC_NAME,
         t4.PROPERTYID,
         t5.NAME AS PROP_NAME,
         t4.VALUE

FROM     ASFACT_DOCUMENTVIEWS_2011_10 AS t2 INNER JOIN
         ASDIM_USERS AS t3 ON t3.USERID = t2.USERID INNER JOIN
         ASDIM_USERPROPERTYVALUES AS t4 ON t4.USERID = t2.USERID INNER JOIN
         ASDIM_KDDOCUMENTS AS t1 ON t1.ID = t2.DOCUMENTID INNER JOIN
         ASDIM_USERPROPERTIES AS t5 ON t4.PROPERTYID = t5.PROPERTYID

WHERE    (t2.DOCUMENTID IN ('33449', '36241', '36566')) AND
         (t4.PROPERTYID IN (26, 156, 157, 158, 159, 325, 160, 162))

ORDER BY t2.DOCUMENTID,
         t3.NAME;

分区问题 我不熟悉某些人提到过的分区概念,并会在此时对其进行研究。

如果重要的话,这些月度表中的每一个只有大约20k行和1.5mb(我们不是一家大公司,这个软件是为那些在每个月表中获得数百万行的公司而设计的)

2 个答案:

答案 0 :(得分:7)

SQL Server中的对象和列名称不能是动态的。

你必须使用动态SQL来构建它,比如使用sp_executesql

...
SET @SQL = 'DOCUMENTS_'+'2011_10';
EXEC sp_executesql @sql ...

这样说,在对象名称中嵌入这样的信息通常是不好的做法。如果您想在一个查询中使用3个月的数据,会发生什么?

答案 1 :(得分:2)

不知道更多 - 有一些选项

  1. 编写动态sql:http://www.tek-tips.com/faqs.cfm?fid=3132

    Set @SQL = 'SELECT * From #TempTable Where EmpID in (' + @INList +')'
    Exec(@SQL)
    

    可能是您正在寻找的,但是

  2. 您是否限制了分区视图,只能从视图中进行访问?它可以将各种事物保存在各自的表中,但是 - 提供对数据的访问,就好像ti在一个地方一样。