在视图中查找动态数据库名称

时间:2012-12-13 20:36:36

标签: sql sql-server

在SQL服务器数据库中,我有这种表:

EVENT201201.dbo.EvAcc
EVENT201202.dbo.EvAcc
EVENT201203.dbo.EvAcc
EVENT201204.dbo.EvAcc
EVENT201205.dbo.EvAcc
...
EVENTYYYYMM.dbo.EvAcc

我也有DBACCES1.dbo.*。我创建了一个这样的查询:

DECLARE @SQL varchar(511)
DECLARE @SQL_ACC varchar(250)
DECLARE @SQL_UClass varchar(250)
DECLARE @SQL_UClassDef varchar(250)
DECLARE @TABLENAME varchar(250)


SELECT @TABLENAME ='EVENT' + CONVERT(char(4), YEAR(GETDATE() - 1)) + CONVERT(char(2), MONTH(GETDATE() - 1))
SELECT @SQL_ACC = '' + QuoteName(@TABLENAME) + '.dbo.EvAcc ON EvAcc.fpointeur = cards.fpointeur'
SELECT @SQL_UClass = 'dbacces1.dbo.UClass ON UClass.fpointeur = cards.fpointeur AND MClass = 1'
SELECT @SQL_UClassDef = 'dbacces1.dbo.UClassDef ON UClassDef.SClass = UClass.SClass'

SELECT @SQL = 'SELECT cards.FPointeur, Ref, Peri, cout, cin, edate FROM dbacces1.dbo.cards INNER JOIN ' + @SQL_ACC + ' INNER JOIN ' + @SQL_UClass

EXEC(@SQL)

它有效,但我需要把它放在视图中。它不起作用。我有这个错误(对不起法国人):

La construction ou l'instruction SQL Déclarer un curseur n'est pas prise en charge.

它表示在视图中不允许声明。

我试图创建一个有价值的表函数,它不起作用,因为我不能在函数中使用函数exec。我有这个错误:

Invalid use of side-effecting or time-dependent operator in 'EXECUTE STRING' within a function.

我也尝试创建过程但我不能在查询中将它用作表格。我试图创建一个仅返回数据库名称的函数,但它不再起作用。

你有解决方案吗?

编辑1 - 解决方案

我创建了一个每月执行的脚本。这是我的剧本:

DECLARE @start_date DATETIME
DECLARE @end_date DATETIME
DECLARE @sql VARCHAR(MAX)
DECLARE @dbname VARCHAR(15)
DECLARE @year VARCHAR(4)
DECLARE @month VARCHAR(2)

--Start the SQL request
SET @sql = 'CREATE VIEW dbo.viewEvAcc AS '

SET @start_date = convert(DATETIME, '01/01/2011', 101)
SET @end_date = GETDATE()

--Loop from the start date to now
WHILE @start_date < @end_date
BEGIN
    --Find new year and month
    SET @year = CONVERT(CHAR(4), YEAR(@start_date))
    SET @month = RIGHT('0' + RTRIM(MONTH(@start_date)), 2);

    --Create the db name with year and month
    SET @dbname = 'EVENT' + @year + @month

    --Concat the SQL Request
    SET @sql = @sql + 'SELECT * FROM ' + @dbname + '.dbo.EvAcc'

    --Update the start date for the month after
    SET @start_date = CONVERT(VARCHAR(8),DATEADD(MONTH,1,CONVERT(VARCHAR(8),@start_date,112)),112)

    --If the date is not the last date, it add a union
    IF @start_date < @end_date
    BEGIN
        SET @sql = @sql + ' UNION ALL '
    END
END

-- drop and create a view with new information
USE dbacces1
IF EXISTS (SELECT TABLE_NAME FROM INFORMATION_SCHEMA.VIEWS WHERE TABLE_NAME = 'viewEvAcc')DROP VIEW dbo.viewEvAcc; 
EXEC(@sql)

3 个答案:

答案 0 :(得分:0)

视图只能包含静态select语句,因此如果要实现dynamic SQL,则需要将其放在存储过程中。您可以按照以下步骤操作:

  1. 使用动态sql创建存储过程 - sp_1
  2. 使用其他查询创建存储过程 - sp_2
  3. 在此存储过程中,调用您的sp_1和insert the results into a temp table
  4. 在查询中加入此临时表。

答案 1 :(得分:0)

也许您可以使用synonims:http://msdn.microsoft.com/en-us/library/ms187552(v=sql.100).aspx

您创建一个静态视图,从同义词对象中选择数据,但在从视图中选择之前,您需要将同义词重新分配给所需数据库中的表。

答案 2 :(得分:0)

如果视图定期更改(即每天),您可以编写作业脚本,并根据需要重新创建(更改)视图。它可能是创建和/或填充新表的工作的一部分。

如果提前创建了空表,请查看创建分区视图以将它们全部联合起来。然后,您可以在查询的基础上添加连接,并将日期约束添加到该查询的where子句中。

Partitioned Views