基于日期时间参数的动态查询

时间:2018-12-26 11:53:00

标签: sql sql-server stored-procedures

我有一个SQL Server数据库,其日期表示名称如下所示,并且每个数据库都包含表A(表A的列如id,datetime,value,value1等)。

  • 2018年1月
  • 2018年2月
  • 2018年3月,依此类推。

我的搜索条件是用户选择的日期(例如,从2018年1月1日到2018年6月1日),我将其传递给存储过程(最大范围为6个月)。我想生成动态查询,以根据传递的日期时间从这些数据库中获取数据。

我发现很难实现该功能。

3 个答案:

答案 0 :(得分:1)

您可以尝试查询

CREATE PROCEDURE Myproc @FromDate DATE, 
                        @ToDate   DATE 
AS 
  BEGIN 
      DECLARE @SQL      NVARCHAR(max)='', 
              @unionall VARCHAR(10)='' 

      WITH cte 
           AS (SELECT @FromDate dt, 
                      1         mont 
               UNION ALL 
               SELECT Dateadd(month, 1, dt) dt, 
                      mont + 1              mont 
               FROM   cte 
               WHERE  mont < Datediff(month, @FromDate, @ToDate) 

              ) 
      SELECT @SQL += @unionall + '
                         select * from [' 
                     + LEFT (CONVERT(VARCHAR, Datename (month, dt )), 3) 
                     + CONVERT (VARCHAR, Year (dt)) 
                     + '].[dbo].[tablename]', 
             @unionall = ' union all ' 
      FROM   cte 

      PRINT @SQL 

      EXECUTE( @SQL) 
  END 

答案 1 :(得分:0)

您在寻找

CREATE PROCEDURE MyProc
  @FromDate DATE,
  @ToDate DATE,
  @Target SysName
AS
BEGIN
  DECLARE @SQL NVARCHAR(MAX)= N'SELECT * FROM [' +
    @Target +
    '] WHERE [Dates] >= @FromDate AND [Dates] <= @ToDate';

  EXECUTE sp_executesql @SQL,
                        N'@FromDate DATE, @ToDate DATE',
                        @FromDate,
                        @ToDate;

END

Demo

据我所知,您可以尝试

CREATE PROCEDURE ProcName
  @FromDate DATE,
  @ToDate DATE
AS
BEGIN
  --Declare a variable to hold the Dynamic SQL
  DECLARE @SQL NVARCHAR(MAX) = N'';
  --Generate the databases names
  WITH CTE AS
  (
    SELECT @FromDate D,
           1 N
    UNION ALL
    SELECT DATEADD(Month, N, @FromDate),
           N + 1
    FROM CTE
    WHERE N <= DATEDIFF(Month, @FromDate, @ToDate)
  )
  --Build the SELECT statement
  SELECT @SQL = @SQL+
                N'SELECT * FROM ['+
                CONVERT(VARCHAR(3), D, 100)+
                CAST(YEAR(D) AS VARCHAR(4))+
                '].dbo.TableName UNION ALL ' --Or UNION as you want
  FROM CTE;
  --Remove the last UNION ALL
  SET @SQL = LEFT(@SQL, LEN(@SQL) - 10); --If UNION then just -6
  --Execute the statement
  EXECUTE sp_executesql @SQL;
END

答案 2 :(得分:0)

您应该查询sys.databases以找到所需的数据库。 然后,由于只能使用数据库的静态声明,因此应创建一个文本选择语句并执行它。

我在我的数据库上尝试了它,并且有效。 这是我的代码:

declare  @date varchar(20) = '2018'

declare @dbName varchar(20)
declare @sSql varchar(200)
declare @sConditions varchar(20) = ''

Set @dbName = (SELECT name FROM master.sys.databases
where name like '%' + @date + '%')

print @dbName

Select @sSql = 'Select * From ' + @dbName + '.dbo.MyDB '
--+ ' Where ' + @sConditions

Execute (@sSql)

如果您需要查询所有适合的年份。这样做:

declare  @date varchar(20) = 'a' 
SELECT name Into #dbnames
FROM master.sys.databases
where name like '%' + @date + '%'  

这带来了所有可连接数据库的表。然后使用循环查询其中的每一个。像光标