如何在 SQL 查询的 FROM 区域中使用动态表名?
原始问题: 我正在使用一个数据库,该数据库每月生成一个新表并将 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;
PARTITIONING QUESTION 我不熟悉一些人提到的分区概念,现在会研究它。
如果重要的话,每个月度表只有大约 20k 行和 1.5mb(我们不是一家大公司,这个软件是为每个月度表中有数百万行的公司设计的)
Original question:
I'm working with a database that generates a new table each month and appends YYYY_MM
to the new table name. I need to write a query that will look at the table for the current month. Date functions aside, I find I'm unable to build table names!
Example table name would be DOCUMENTS_2011_10
.
I tried to use a basic script like this but it fails on syntax issue:
SELECT * FROM ('DOCUMENTS_'+'2011_10')
Any suggestions?
ADDITIONAL INFO:
The tables are being generated by our enterprise portal application (Oracle WebCenter Interaction). It is out of my control to redesign this application to change how it handles its data.
I've been asked to extract a report showing key data from these tables which are generated monthly.
My approach was going to be to create a SQL Reporting Service subscription that will email the data each month in Excel format.
I needed help with this query to plug it into the reporting service so I wouldn't have to dabble with the query each month to change the tablename.
Because the reporting service will trigger each month and generate the reports, an archive of data, or any type of ad hoc capability are not needed.
Using dynamic SQL I was able to set the table name, unfortunately when I try to add the rest of my query it complains of a character limit issue. Any idea how to get around that?
This gets me the correct table:
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)
This is the other query that all needs to get executed but won't fit into the @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 QUESTION
I'm unfamiliar with the partitioning concept that some folks have mentioned and will look into it at this time.
In case it matters, each of these monthly tables is only about 20k rows and 1.5mb (we aren't a big company, this software was designed for companies that get millions of rows in each of these monthly tables)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
SQL Server 中的对象和列名称不能是动态的。
您必须使用动态 SQL 来构建它,例如使用 sp_executesql
来说,在对象名称中嵌入这样的信息通常是不好的做法。如果您希望在一次查询中获取 3 个月的数据,会发生什么情况?
Object and columns names can not be dynamic in SQL Server.
You'd have to use dynamic SQL to build it up, say with sp_executesql
Saying that, embedding info like this in an object name generally bad practice. What happens if you want 3 months of data in one query?
无需了解更多信息 - 有许多选项
编写动态 sql:http: //www.tek-tips.com/faqs.cfm?fid=3132
可能是您正在寻找的,但是
您是否考虑过分区视图,并且仅从视图进行访问?这样做的好处是可以将数据保存在各自的表中,同时提供对数据的访问,就像在一个地方一样。
Without knowing more - there are a numebr of options
writing dynamic sql: http://www.tek-tips.com/faqs.cfm?fid=3132
may be what you are looking for, however
Have you conisdered partitioned views, and only accessing from the view? It would have the bemefit of keeping things in their individual tables, yet - provide access to the data as if ti was in one place.