使用游标在 T-SQL 中插入 table 名称和记录数(消息 207,级别 16,状态 1,第 1 行无效列名称 'table_x')
Inserting table names and the number of records in T-SQL using cursor (Msg 207, Level 16, State 1, Line 1 Invalid column name 'table_x')
我收到来自特定供应商的数据(多个文件),我需要记录 table 名称以及 records/table 的数量。我尝试使用以下代码:
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
我收到如下错误信息:
Msg 207, Level 16, State 1, Line 1 Invalid column name 'table_1'.
Msg 207, Level 16, State 1, Line 1 Invalid column name 'table_2'. (...)
Msg 207, Level 16, State 1, Line 1 Invalid column name 'table_n'.
这可能意味着光标正在获取 table 名称,因此错误可能出在我的动态 SQL 中,但我无法修复它。
我使用 MS Server 2012,是 SQL 的一个相对初级的用户。如有任何有用的提示指出我的错误,将不胜感激。
您的动态 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
为什么您的声明不符合以下原因:
'...cast(' + @Tablename + N' as varchar (100))...'
这会隐藏到 SQL
CAST(YourTableName AS varchar(100))
其中,您可能会发现没有意义。您希望 YourTableName
包含在单引号中,并且可能作为 nvarchar
。你可以通过这样做来实现:
'...cast(N' + QUOTENAME(@Tablename,N'''') + N' as nvarchar (100))...'
您可以 "easily" 将其构建到单个语句中,然后使用 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;
我收到来自特定供应商的数据(多个文件),我需要记录 table 名称以及 records/table 的数量。我尝试使用以下代码:
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
我收到如下错误信息:
Msg 207, Level 16, State 1, Line 1 Invalid column name 'table_1'.
Msg 207, Level 16, State 1, Line 1 Invalid column name 'table_2'. (...)
Msg 207, Level 16, State 1, Line 1 Invalid column name 'table_n'.
这可能意味着光标正在获取 table 名称,因此错误可能出在我的动态 SQL 中,但我无法修复它。 我使用 MS Server 2012,是 SQL 的一个相对初级的用户。如有任何有用的提示指出我的错误,将不胜感激。
您的动态 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
为什么您的声明不符合以下原因:
'...cast(' + @Tablename + N' as varchar (100))...'
这会隐藏到 SQL
CAST(YourTableName AS varchar(100))
其中,您可能会发现没有意义。您希望 YourTableName
包含在单引号中,并且可能作为 nvarchar
。你可以通过这样做来实现:
'...cast(N' + QUOTENAME(@Tablename,N'''') + N' as nvarchar (100))...'
您可以 "easily" 将其构建到单个语句中,然后使用 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;