Возврат данных между датами "Кому" и "От" в динамическом SQL-запросе

этот код сейчас не работает. Я попытался добавить параметры @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

person Mari    schedule 23.05.2018    source источник
comment
Для чего предназначен ваш CTE DateRange()? Также вам нужно потратить время на определение конкретной проблемы, которую вы хотите, чтобы мы рассмотрели. Размещать столько кода бессмысленно. Прочитайте это: stackoverflow.com/help/mcve   -  person MatBailie    schedule 23.05.2018
comment
почему это select (''@FromDate'')...? не похоже на другую конкатенацию в вашем динамическом sql?   -  person LONG    schedule 23.05.2018


Ответы (2)


Когда вы выполняете SQL через EXEC или sp_executesql, область действия изменяется, а локальные временные таблицы и переменные больше не доступны.

DECLARE @variable INT = 10

EXEC ('SELECT @variable')

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

Чтобы ваш динамический SQL работал правильно, вам нужно будет впечатать значение вашей переменной непосредственно в SQL с помощью соответствующей функции CONVERT (вам придется записать ее как литерал).

Итак, когда вы делаете

'select  (''@FromDate'')'

вам действительно придется сделать

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

Убедитесь, что его можно правильно преобразовать из строкового литерала в правильный формат.

person EzLo    schedule 23.05.2018

В предложении where для выбора для изменения курсора

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

to

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
'
person MAUB    schedule 23.05.2018