Вставка имен таблиц и количества записей в T-SQL с использованием курсора (Msg 207, Уровень 16, Состояние 1, Строка 1 Неверное имя столбца 'table_x') - PullRequest
0 голосов
/ 21 марта 2019

Я получаю данные от конкретного поставщика (несколько файлов), и мне нужно зарегистрировать имя таблицы, а также количество записей / таблицы. Я пытался использовать следующий код:

declare 
@TableName sysname,
@sqlstring nvarchar (1000);


DECLARE db_cursor CURSOR FOR 
SELECT Name 
FROM DataBase.dbo.Sysobjects 
WHERE name like '%SupplierName%' and crdate = '20190320';

if OBJECT_ID(N'tempdb..#Mytable') is not null
exec ('drop table #MyTable');

create table #MyTable (
    TableName varchar (100),
    Qty int);

OPEN db_cursor  
FETCH NEXT FROM db_cursor INTO @tablename  


WHILE @@FETCH_STATUS = 0  
BEGIN  
  set @sqlstring = N'insert into #MyTable (TableName, Qty) select  cast(' + @Tablename + N' as varchar (100)), (select count(*) from DataBase.dbo.' + quotename(@Tablename) + N' as Qty)'  
  EXECUTE master.dbo.sp_executesql @sqlstring
  FETCH NEXT FROM db_cursor INTO @tablename 
END  

CLOSE db_cursor  
DEALLOCATE db_cursor

Я получаю сообщение об ошибке:

Сообщение 207, Уровень 16, Состояние 1, Строка 1 Неверное имя столбца 'table_1'.

Сообщение 207, Уровень 16, Состояние 1, Строка 1 Неверное имя столбца 'table_2'. (...)

Сообщение 207, Уровень 16, Состояние 1, Строка 1 Неверное имя столбца 'table_n'.

, что, возможно, означает, что курсор выбирает имена таблиц, поэтому ошибка, вероятно, в моем динамическом SQL, но я не смог ее исправить. Я использую MS Server 2012, я относительно начинающий пользователь SQL. был бы признателен за любые полезные советы, указывающие на мою ошибку.

Ответы [ 2 ]

0 голосов
/ 21 марта 2019

Причина, по которой ваше утверждение не соответствовало этому, объясняется следующим:

'...cast(' + @Tablename + N' as varchar (100))...'

Это будет скрыто в SQL

CAST(YourTableName AS varchar(100))

Что, как вы, вероятно, видите, не 'не имеет смысла.Вы хотите, чтобы YourTableName был заключен в одинарные кавычки и, вероятно, как nvarchar.Вы можете добиться этого, выполнив это вместо этого:

    '...cast(N' + QUOTENAME(@Tablename,N'''') + N' as nvarchar (100))...'

Вместо того, чтобы использовать курсор, вы могли бы намного легче "упростить" построение этого в одном выражении и использовать PRINT для устранения неполадок.Это должно работать для вашей цели, но я не могу проверить, поскольку у меня нет доступа к вашей системе:

CREATE TABLE #MyTable(TableName sysname,
                      Qty int);

DECLARE @SQL nvarchar(MAX);

SET @SQL = N'INSERT INTO #MyTable(TableName, Qty)' + NCHAR(13) + NCHAR(10) +
           STUFF((SELECT N'UNION ALL' + NCHAR(13) + NCHAR(10) +
                         N'SELECT N' + QUOTENAME([name],N'''') + N',' + NCHAR(13) + NCHAR(10) +
                         N'       (SELECT COUNT(*) FROM dbo.' + QUOTENAME([name]) + N')'
                  FROM sys.sysobjects  --I assume this should have been sys
                  WHERE [name] LIKE N'%SupplierName%'
                    AND crdate = '20190320'
                  FOR XML PATH(N''),TYPE).value('.','nvarchar(MAX)'),1,11,N'') + N';'
--PRINT @SQL --Your debugging best friend
EXEC sp_executesql @SQL;
0 голосов
/ 21 марта 2019

Ваш динамический SQL генерирует ...

select  cast(Tablename as varchar (100)), (select count(*) from DataBase.dbo.[Tablename]) as Qty)

и вам нужно

select  cast('Tablename' as varchar (100)), (select count(*) from DataBase.dbo.[Tablename]) as Qty)

, вы можете решить его следующим образом

set @sqlstring = N'insert into #MyTable (TableName, Qty) select  cast(' + quotename(@Tablename, '''') + N' as varchar (100)), (select count(*) from DataBase.dbo.' + quotename(@Tablename) + N' as Qty)' 

quootename(@Tablename, '''')добавит отсутствующую цитату, чтобы получить «TableName» как значение, а не как ссылку

Я бы изменил его, выглядит более читабельным, но это ваш вызов

set @sqlstring = N'SELECT ' + QUOTENAME(@TableName, '''') + N',COUNT(1) 
    FROM DataBase.dbo.' + quotename(@Tablename) 
INSERT #MyTable (TableName, Qty)
EXECUTE sp_executesql @sqlstring
FETCH NEXT FROM db_cursor INTO @tablename
...