我的数据库包含自 2009 年以来每个月的日志。每个表名都遵循以下模式: dbo.LOG[year][month] --> dbo.LOG200909 现在我需要合并所有这些表来运行查询。是否有任何捷径可以做到这一点,而无需通过硬编码表名将它们一一合并,例如将来需要较少维护的名称范围?因为这些表一直在添加,我希望查询继续使用新添加的表。顺便说一句,我对 SQL 几乎是新手。
2 回答
0
您可以使用存储过程:
DROP Procedure IF EXISTS test_procedure;
GO
CREATE PROCEDURE test_procedure
(@prefix Nvarchar(100),
@start_year int,
@start_month int,
@end_year int,
@end_month int
)
AS
BEGIN
declare @sql varchar(8000)
declare @year int
set @year = @start_year + 1
select @sql='select * from ' + @prefix + CAST(@start_year as varchar(10))
WHILE @year <= @end_year
BEGIN
select @sql +=' union ' + @prefix + CAST(@year as varchar(10))
SET @year = @year + 1
END
select @sql
--execute(@sql)
END;
GO
exec test_procedure @prefix = 'abc', @start_year = 2000, @start_month=1, @end_year = 2005, @end_month=1;
这将导致:“select * from abc2000 union abc2001 union abc2002 union abc2003 union abc2004 union abc2005”
您可以使用“执行”来运行它,而不是打印该语句。
您需要增强循环来计算月份。
于 2020-10-05T15:20:51.980 回答
0
DECLARE myCursor cursor
FOR SELECT QUOTENAME(T.TABLE_SCHEMA)+'.'+QUOTENAME(T.TABLE_NAME) TABLE_NAME
FROM INFORMATION_SCHEMA.TABLES T
WHERE T.TABLE_NAME LIKE 'Log20[0-9][0-9][0-1][0-9]'
AND T.TABLE_SCHEMA = 'dbo'
ORDER BY T.TABLE_NAME;
IF OBJECT_ID('tempdb..#Results','U') IS NOT NULL
DROP TABLE #Results;
CREATE TABLE #Results -- Same structure as Log tables
(
Col1 int,
Col2 nvarchar(20)
-- ,...
);
OPEN myCursor
DECLARE @TABLE_NAME sysname
FETCH NEXT FROM myCursor INTO @TABLE_NAME
WHILE @@FETCH_STATUS = 0 BEGIN
DECLARE @sSql as nvarchar(MAX)
SET @sSql = 'INSERT INTO #Results(col1,Col2, Col2...) '
+ 'SELECT * FROM ' + @TABLE_NAME
EXEC(@sSql);
FETCH NEXT FROM myCursor INTO @TABLE_NAME
END
CLOSE myCursor
DEALLOCATE myCursor
SELECT *
FROM #Results
于 2020-10-05T15:04:18.180 回答