代码之家  ›  专栏  ›  技术社区  ›  Dikshit Karki

在T-SQL中循环遍历游标

  •  -2
  • Dikshit Karki  · 技术社区  · 4 年前

    我正在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-16\20220316032322.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
    

    但我有一个错误:

    列名sfilename无效
    必须声明表变量@sserver

    1 回复  |  直到 4 年前
        1
  •  2
  •   Aaron Bertrand    4 年前

    这是行不通的:

    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);
    

    请复习 this collection of links .