我想整理一个查询但是为了避免使用游标。我们有PDF文件存储在多个表中。每张桌子一年。所以我们有表名,如:
"Files_2012", "Files_2013", "Files_2014", etc.
然后我们有一个主表(称为Files
),其中包含存储文件的表。
这是布局:
=======================================
FILES
=======================================
FileId | RecordId | FileTableName
---------------------------------------
104 | 7108162 | Files_2013
105 | 7108162 | Files_2014
106 | 7108162 | Files_2013
年度表格如下:
=======================================
FILES_2013
=======================================
FileId | FileData (varbinary
---------------------------------------
104 | 0x255044462D312E340A25E2E3CFD30D...
106 | 0x897444462D312E340A25E2E3CFD30D...
=======================================
FILES_2014
=======================================
FileId | FileData (varbinary
---------------------------------------
105 | 0x556044462D312E340A25E2E3CFD30D...
我的查询需要根据RecordId
返回记录。因此,在此示例中,所有3个Files.RecordId
值都相同。我需要为所有3条记录返回FileData
列,如下所示:
=======================================
My returned records
=======================================
FileId | FileData (varbinary
---------------------------------------
104 | 0x255044462D312E340A25E2E3CFD30D...
105 | 0x556044462D312E340A25E2E3CFD30D...
106 | 0x897444462D312E340A25E2E3CFD30D...
我该怎么做?如果它有帮助,这是我到目前为止的查询,虽然我可能会离开。我将FileTableName
值存储到临时表和&我希望能以这种方式与他们合作,但在此之后我就陷入了困境:
DECLARE @recordId INT
CREATE TABLE #tmpFiles (FileId int, FileTableName varchar(100), FileData varbinary(max))
SET @recordId = 7108162
INSERT INTO #tmpFiles (FileId, FileTableName)
SELECT FileId, FileTableName
FROM dbo.Files
WHERE RecordId = @recordId
UPDATE t
SET t.FileData = f.FileData
FROM #tmpFiles t
INNER JOIN Files_2013 f ON t.FileId = f.FileId
感谢您提供的任何帮助。
答案 0 :(得分:3)
假设您事先知道表名,可以使用UNION ALL
:
DECLARE @recordId INT = 7108162;
WITH cte(FileId, FileData, Year) AS
(
SELECT FileId , FileData, 2012 AS [Year]
FROM FILES_2012
UNION ALL
SELECT FileId , FileData, 2013
FROM FILES_2013
UNION ALL
SELECT FileId , FileData, 2014
FROM FILES_2014
)
SELECT c.*
FROM FILES f
JOIN cte c
ON f.FileId = c.FileId
WHERE f.RecordId = @RecordId;
如果你不知道表名(我怀疑它们有共同的名称模式),你需要使用Dynamic-SQL但重新考虑不同的选项。
阅读The Curse and Blessings of Dynamic SQL by Erland Sommarskog
SELECT * FROM sales + @yymm
这是前一种情况的变体,其中有一套 实际上描述同一实体的表。 所有表都有 相同的列,名称包括一些分区组件, 通常是年份,有时也是月份。新表创建为 新年/月开始。
在这种情况下,每个表写一个存储过程并不是真的 可行。至少,因为用户可能想要指定日期 搜索的范围,所以即使每个表有一个程序,你也可以 仍然需要动态调度员。
现在,让我们说清楚:这是一个有缺陷的桌面设计。你 每个月不应该有一个销售表,你应该有一个 sales表和表名中出现的月份应该是 联合销售表中主键的第一列。但是你 可能会陷入无法轻易更改的遗留应用程序 桌子设计。而且,诚然,有些情况下 分区是有道理的。该表可能很大(比如说超过10 GB) 大小),或者您希望能够快速老化旧数据。但就是这样 你应该正确分区。
在下文中,我将介绍三种处理方法 不使用动态SQL进行分区。
可能的解决方案:
- 分区表
- 观看和分区视图
- 兼容性视图