原始问题: 我正在处理一个数据库,每个月都会生成一个新表,并将YYYY_MM
附加到新的表名。我需要编写一个查询,查看当前月份的表格。抛开日期函数,我发现我无法构建表名!如何在SQL查询的FROM区域中使用动态表名称?
实施例表名称将是DOCUMENTS_2011_10
。
我试图用一个基本的脚本是这样,但它没有对语法问题:
SELECT * FROM ('DOCUMENTS_'+'2011_10')
有什么建议?
附加信息:正在我们的企业门户应用程序(甲骨文的WebCenter交互)产生 表。重新设计这个应用程序以改变它的数据处理方式是不可能的。
我一直在问,提取出从每月生成这些表主要数据报告。
我的办法将是创建一个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;
PARTITIONING问题 我不熟悉一些人提到的分区概念,并且会在这个时候查看它。
万一它很重要,每个这些月表只有大约20K行和1.5MB(我们不是一个大公司,这个软件是为在这些月表中获得数百万行的公司设计的)
您是否考虑过使用SQL Server的分区功能来水平分解表?如果完全可以避免动态命名的表,它将为您节省很多动态SQL的麻烦。 – JohnFx
是的,应该使用分区,如果可用的话。否则...并不完全消除对动态SQL的需求,但我们在这里所做的一件事是为所需的表创建一个临时_alias_(动态),然后在我们的SQL中使用别名的(常数)名称。如果您使其能够汇总来自多个来源(例如三个月)的数据,这也具有这样的效果。 –
如果动态SQL不适合变量,并且没有使用分区,那么可以使变量的内容更短。只需抓住一个表并将结果放入临时表中即可。然后用临时表而不是动态命名的表再次执行主查询,而不需要更长查询所需的动态SQL。 –