【问题标题】:Returning data between To and From Dates in Dynamic SQL Query在动态 SQL 查询中返回 To 和 From 日期之间的数据
【发布时间】:2018-05-23 13:37:27
【问题描述】:

此代码现在不起作用我尝试添加@FromDate 和@ToDate 参数,以便我可以选择我希望查询运行的日期。请问有什么代码校正器可以帮忙吗?消息是我需要声明标量变量 @FromDate 和 @ToDate 但我已经声明了它们?显然,“As”附近的语法也不正确。

DECLARE @DatabaseName VARCHAR(100)
DECLARE @SchemaName VARCHAR(100) 
DECLARE @TableName VARCHAR(100)
DECLARE @ColumnName VARCHAR(100)
DECLARE @FullyQualifiedTableName VARCHAR(500)
DECLARE @DataType VARCHAR(50)
DECLARE @FromDate DATETIME
DECLARE @ToDate DATETIME

Declare @MySchemaName varchar(100) = 'MySystem%'

SET @FromDate = '16 May 2018'
SET @ToDate = '23 May 2018'

      ;WITH dateRange AS
(
    SELECT [Date] = DATEADD(dd, 1, DATEADD(dd, -1,@FromDate))
    WHERE DATEADD(dd, 1, @FromDate) < DATEADD(dd, 1,@ToDate)
)

    SELECT @ColumnName = COALESCE(@ColumnName, '[') + CONVERT(VARCHAR, [Date], 111) + '],['
    FROM dateRange
    OPTION (maxrecursion 0)

    SET @ColumnName = SUBSTRING(@ColumnName, 1, LEN(@ColumnName)-2)

    SELECT @ColumnName


--Create Temp Table to Save Results
IF OBJECT_ID('tempdb..#Results') IS NOT NULL
    DROP TABLE #Results

CREATE TABLE #Results (
    DatabaseName VARCHAR(100)
    ,SchemaName VARCHAR(100)
    ,TableName VARCHAR(100)
    ,ColumnName VARCHAR(100)
    ,ColumnDataType VARCHAR(50)
    ,StartDate Datetime2(7)
    ,EndDate Datetime2(7)
    ,TotalRowCount int
    ,NullCount int
    ,InvalidCount int
    ,ValidityCheck VARCHAR(25)




    )

    ---------------------------------------------------------DateOfBirth----------------------------------------------------------------

    DECLARE Cur CURSOR
FOR
SELECT DB_Name() AS DatabaseName
    ,s.[name] AS SchemaName
    ,t.[name] AS TableName
    ,c.[name] AS ColumnName
    ,'[' + DB_Name() + ']' + '.[' + s.name + '].' + '[' + T.NAME + ']' AS FullQualifiedTableName
    ,d.[name] AS DataType
    ,t.[create_date] AS StartDate
    ,t.[create_date] AS EndDate
FROM sys.schemas s
INNER JOIN sys.tables t ON s.schema_id = t.schema_id
INNER JOIN sys.columns c ON t.object_id = c.object_id
INNER JOIN sys.types d ON c.user_type_id = d.user_type_id
    WHERE s.name like @MySchemaName -----comment out of for all database
    and(c.name LIKE '%dob%' or c.name like '%birth%' )
    and t.create_date = @FromDate
    and t.create_date = @ToDate
   AND is_identity = 0

OPEN Cur

FETCH NEXT
FROM Cur
INTO @DatabaseName
    ,@SchemaName
    ,@TableName
    ,@ColumnName
    ,@FullyQualifiedTableName
    ,@DataType
    ,@FromDate
    ,@ToDate

WHILE @@FETCH_STATUS = 0 


BEGIN


    DECLARE @SQL VARCHAR(MAX) = NULL


    SET
     @SQL = ' Select ''' + @DatabaseName + ''' AS DatabaseName, ''' + @SchemaName + ''' AS SchemaName,
      ''' + @TableName + ''' AS TableName,
      ''' + @ColumnName + ''' AS ColumnName,
      ''' + @DataType + ''' AS DataType,


      (select  (''@FromDate'')
      As StartDate,
      (select (''@ToDate'')
      As EndDate,
      (select count(*)  from ' + @FullyQualifiedTableName + ' )
      AS TotalRowCount,
      (Select CAST(SUM(CASE WHEN ' + @ColumnName + ' IS  NULL THEN 1 ELSE 0 END) as int)  from ' + @FullyQualifiedTableName + ' )
      AS NullCount,
        (Select sum (Case when  ' + @ColumnName + ' is not null and ( ' + @ColumnName + ' <= ''1900-01-01''
     or ' + @ColumnName + '  > getdate()) then 1 else 0 end) from ' + @FullyQualifiedTableName + ' )
    AS  InvalidCount,
        (Select ''DateOfBirth'') 
        As ValidityCheck
    '


  PRINT @SQL



    INSERT INTO #Results
    EXEC (@SQL)

    FETCH NEXT
    FROM Cur
    INTO @DatabaseName
        ,@SchemaName
        ,@TableName
        ,@ColumnName
        ,@FullyQualifiedTableName
        ,@DataType
        ,@FromDate
        ,@ToDate
END



CLOSE Cur

DEALLOCATE Cur
SELECT *
FROM #Results
order by tableName desc
    --drop table #Results

【问题讨论】:

  • 您的 CTE DateRange() 打算做什么?此外,您还需要花时间找出您希望我们查看的确切问题。发布那么多代码是没有意义的。阅读:stackoverflow.com/help/mcve
  • 为什么是select (''@FromDate'')...?不像动态 sql 中的其他串联?

标签: sql sql-server ssms-2016


【解决方案1】:

当您通过EXECsp_executesql 执行 SQL 时,范围更改和本地临时表和变量不再可访问。

DECLARE @variable INT = 10

EXEC ('SELECT @variable')

--Msg 137, Level 15, State 2, Line 1
--Must declare the scalar variable "@variable".

为了让您的动态 SQL 正常工作,您必须使用正确的 CONVERT 函数将变量的值直接印在 SQL 上(您必须将其写为文字)。

所以当你这样做时

'select  (''@FromDate'')'

你实际上必须这样做

'select  (''' + CONVERT(VARCHAR(30), @FromDate) + ''')'

确保它可以正确地从字符串文字转换为正确的格式。

【讨论】:

    【解决方案2】:

    在 where 子句中用于光标更改的选择

    and t.create_date = @FromDate
    and t.create_date = @ToDate
    

    and t.create_date >= @FromDate
    and t.create_date <= @ToDate
    

    然后在光标内将 SET @SQL = ... 块更改为

    SET
     @SQL = ' Select ''' + @DatabaseName + ''' AS DatabaseName, ''' + @SchemaName + ''' AS SchemaName,
      ''' + @TableName + ''' AS TableName,
      ''' + @ColumnName + ''' AS ColumnName,
      ''' + @DataType + ''' AS DataType,
      (select  ''' + convert(varchar(30),@FromDate,101) + ''') As StartDate,
      (select ''' + convert(varchar(30),@ToDate,101) + ''') As EndDate,
      (select count(*)  from ' + @FullyQualifiedTableName + ' ) AS TotalRowCount,
      (Select CAST(SUM(CASE WHEN ''' + @ColumnName + ''' IS  NULL THEN 1 ELSE 0 END) as int)  from ' + @FullyQualifiedTableName + ' )
      AS NullCount,
        (Select sum (Case when  ' + @ColumnName + ' is not null and ( ' + @ColumnName + ' <= ''1900-01-01''
     or ' + @ColumnName + '  > getdate()) then 1 else 0 end) from ' + @FullyQualifiedTableName + ' )
    AS  InvalidCount,
        (Select ''DateOfBirth'') 
        As ValidityCheck
    '
    

    【讨论】:

      猜你喜欢
      • 2021-10-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多