【发布时间】:2011-12-30 20:33:51
【问题描述】:
原问题:
我正在使用一个每月生成一个新表并将YYYY_MM 附加到新表名的数据库。我需要编写一个查询来查看当前月份的表。除了日期函数,我发现我无法建立表名!
示例表名称为DOCUMENTS_2011_10。
我尝试使用这样的基本脚本,但在语法问题上失败了:
SELECT * FROM ('DOCUMENTS_'+'2011_10')
有什么建议吗?
附加信息: 这些表是由我们的企业门户应用程序(Oracle WebCenter Interaction)生成的。我无法控制重新设计此应用程序以更改其处理数据的方式。
我被要求从每月生成的这些表中提取显示关键数据的报告。
我的方法是创建一个 SQL 报告服务订阅,每月以 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(我们不是一家大公司,这个软件是为在每个月度表中获得数百万行的公司设计的)
【问题讨论】:
-
您是否考虑过使用 SQL Server 的分区功能来水平拆分表?如果您完全可以避免动态命名的表,那么动态 SQL 将为您省去很多麻烦。
-
是的,如果可用的话,应该使用分区。否则......不会完全消除对动态 SQL 的需求,但我们在这里所做的一件事是为所需表创建一个临时 alias(动态),然后使用(常量) SQL 中别名的名称。如果您将其设为视图,这也会产生以下效果:能够聚合来自多个来源(例如三个月)的数据。
-
如果动态 SQL 不适合变量,并且您没有使用分区,您可以缩短变量的内容。只需抓住一张桌子并将结果放入临时表中。然后再次使用临时表而不是动态命名的表进行主查询,更长的查询不需要动态 SQL。
标签: sql sql-server-2005 sql-server-2008 partitioning dynamic-sql