In a SQL server database I have have this kind of table :
EVENT201201.dbo.EvAcc
EVENT201202.dbo.EvAcc
EVENT201203.dbo.EvAcc
EVENT201204.dbo.EvAcc
EVENT201205.dbo.EvAcc
...
EVENTYYYYMM.dbo.EvAcc
I also have DBACCES1.dbo.*
. I created a query like this :
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)
It works but I need to put this in a view. It doesn't work. I have this error (sorry for the french) :
La construction ou l'instruction SQL Déclarer un curseur n'est pas prise en charge.
It say than declare is not allowed in a view.
I tried to create a valued table function and it doen't work because I can't use the function exec
with a string in a function. I have this error :
Invalid use of side-effecting or time-dependent operator in 'EXECUTE STRING' within a function.
I also tried to create procedure but I can't use it as a table in my query. I tried to create a function which return the database name only but it doen't work again.
Do you have any solution?
EDIT 1 - Solution
I create a script executed each month. This is my script :
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)