在 T-SQL 中循环游标
Looping through the cursor in T-SQL
我正在 T-SQL:
中创建一个过程
CREATE PROCEDURE usp_QC1
AS
BEGIN
DECLARE @tablename varchar(100);
DECLARE @sfilename varchar(100);
DECLARE @rread varchar(100);
DECLARE @rwrite varchar(100);
DECLARE @sserver varchar(100);
DECLARE @dbname varchar(100);
DECLARE cur_tracking CURSOR FOR
SELECT
[TableName],
sfilename,
[RecordsRead],
[RecordsWritten],
[SQLServer],
[SQLDatabase]
FROM
[ADataTracker].[dbo].[TrackerLoadLog]
WHERE
LOWER(datagroup) LIKE '%Oracle RMS%'
AND SUBSTRING(sfilename, 1, 10) = '2022-03-16'
OPEN cur_tracking;
FETCH NEXT FROM cur_tracking INTO @tablename, @sfilename, @rread, @rwrite, @sserver, @dbname;
WHILE @@Fetch_status = 0
BEGIN
SELECT
sfilename, COUNT(*)
FROM
@sserver + '.dbo.' + @dbname
WHERE
sfilename = @sfilename
GROUP BY
sfilename
FETCH NEXT FROM cur_tracking INTO @tablename, @sfilename, @rread, @rwrite, @sserver, @dbname;
END;
CLOSE cur_tracking;
DEALLOCATE cur_tracking;
END
游标cur_tracking
正在保存数据(只显示1条记录)
---------------------------------------------------------------------------------------------------------------------------
TableName |sfilename | RecordsRead |RecordsWritten |SQLServer |SQLDatabase |
History |2022-03-16220316032322.dat| 5819560 |5819560 |a.stg.sql.ccaintranet.com |DataRms_Back |
所以游标有服务器,数据库名,表名的所有信息。我想转到每个 server.db.table
并使用这些游标元素检索信息:
SELECT sfilename, COUNT(*)
FROM @sserver + '.dbo.' + @dbname
WHERE sfilename = @sfilename
GROUP BY sfilename
但是我得到一个错误:
invalid column name sfilename
must declare the table variable @sserver
这永远行不通:
select sfilename,count(*) from @sserver+'.dbo.'+@dbname
你不能像这样参数化实体名称(数据库也出现在模式之前,你完全错过了 @tablename
)。
相反,您可以这样做:
DECLARE @sql nvarchar(max), @exec nvarchar(1000);
...
-- then inside the cursor:
SET @sql = N'select sfilename = @sfilename,count(*)
FROM dbo.' + QUOTENAME(@tablename)
+ N' WHERE sfilename = @sfilename;';
SET @exec = QUOTENAME(@dbname) + N'.sys.sp_executesql';
EXEC @exec @sql, N'@sfilename varchar(100)', @sfilename;
请注意,所有这些都需要 nvarchar(128)
,您可以对多个变量使用相同的 DECLARE
以减轻眼睛疲劳:
DECLARE @tablename nvarchar(128),
@sfilename nvarchar(128),
@dbname nvarchar(128);
我正在 T-SQL:
中创建一个过程CREATE PROCEDURE usp_QC1
AS
BEGIN
DECLARE @tablename varchar(100);
DECLARE @sfilename varchar(100);
DECLARE @rread varchar(100);
DECLARE @rwrite varchar(100);
DECLARE @sserver varchar(100);
DECLARE @dbname varchar(100);
DECLARE cur_tracking CURSOR FOR
SELECT
[TableName],
sfilename,
[RecordsRead],
[RecordsWritten],
[SQLServer],
[SQLDatabase]
FROM
[ADataTracker].[dbo].[TrackerLoadLog]
WHERE
LOWER(datagroup) LIKE '%Oracle RMS%'
AND SUBSTRING(sfilename, 1, 10) = '2022-03-16'
OPEN cur_tracking;
FETCH NEXT FROM cur_tracking INTO @tablename, @sfilename, @rread, @rwrite, @sserver, @dbname;
WHILE @@Fetch_status = 0
BEGIN
SELECT
sfilename, COUNT(*)
FROM
@sserver + '.dbo.' + @dbname
WHERE
sfilename = @sfilename
GROUP BY
sfilename
FETCH NEXT FROM cur_tracking INTO @tablename, @sfilename, @rread, @rwrite, @sserver, @dbname;
END;
CLOSE cur_tracking;
DEALLOCATE cur_tracking;
END
游标cur_tracking
正在保存数据(只显示1条记录)
---------------------------------------------------------------------------------------------------------------------------
TableName |sfilename | RecordsRead |RecordsWritten |SQLServer |SQLDatabase |
History |2022-03-16220316032322.dat| 5819560 |5819560 |a.stg.sql.ccaintranet.com |DataRms_Back |
所以游标有服务器,数据库名,表名的所有信息。我想转到每个 server.db.table
并使用这些游标元素检索信息:
SELECT sfilename, COUNT(*)
FROM @sserver + '.dbo.' + @dbname
WHERE sfilename = @sfilename
GROUP BY sfilename
但是我得到一个错误:
invalid column name sfilename
must declare the table variable @sserver
这永远行不通:
select sfilename,count(*) from @sserver+'.dbo.'+@dbname
你不能像这样参数化实体名称(数据库也出现在模式之前,你完全错过了 @tablename
)。
相反,您可以这样做:
DECLARE @sql nvarchar(max), @exec nvarchar(1000);
...
-- then inside the cursor:
SET @sql = N'select sfilename = @sfilename,count(*)
FROM dbo.' + QUOTENAME(@tablename)
+ N' WHERE sfilename = @sfilename;';
SET @exec = QUOTENAME(@dbname) + N'.sys.sp_executesql';
EXEC @exec @sql, N'@sfilename varchar(100)', @sfilename;
请注意,所有这些都需要 nvarchar(128)
,您可以对多个变量使用相同的 DECLARE
以减轻眼睛疲劳:
DECLARE @tablename nvarchar(128),
@sfilename nvarchar(128),
@dbname nvarchar(128);