SQL 将光标插入临时 Table 并从临时 Table 获取

SQL Cursor to Insert into Temporary Table and Fetch From Temparory Table

先生,

我已经构建了一个 SQL 查询,使用 Cursor 作为 @AllRecords 将值插入到临时 Table 中,然后从该临时 table 中获取值。但是当我从 table 中获取值时,它在最后一条语句中向我显示错误(错误:@AllRecords 附近的语法不正确)。下面是我的代码:

DECLARE @ColName varchar(20)=null,
        @Query varchar(MAX)=null,
        @DepartmentName varchar(50)=null,
        @deptt_code varchar(4)=null,
        @DistrictId varchar(4)='0001',
        @Deptt_Id char(4)=null,
        @stYear varchar(4)=null, 
        @cYear varchar(4)=null,
        @yr varchar(9)='2017-2018',
        @tno int

BEGIN
        set @stYear = SUBSTRING(@yr,0,5)
        set @cYear = SUBSTRING(@yr,6,4)

--DECLARE & SET COUNTER
DECLARE @counter int
SET @counter = 1

--CREATE DYNAMIC TABLE WITH COLs
DECLARE @AllRecords table
(
  department_name varchar(50),
  project_name varchar(100),
  department_code varchar(4)
 )

--*** Declare Cursor
DECLARE cur_FetchDepartmentName CURSOR READ_ONLY
 FOR 
  select deptt_code,deptt_name+'('+ RTRIM(LTRIM(deptt_short))+')' as dept_name from m_Department 
  where deptt_code in (select distinct department_code from t_Project_Details where district_id=@DistrictId
  and financial_year=@yr)

OPEN cur_FetchDepartmetName

fetch next from cur_FetchDepartmetName into 
@deptt_code, @DepartmentName

--LOOP UNTIL RECORDS ARE AVAILABLE
while @@FETCH_STATUS=0
   BEGIN
      if(@tno=0)
          BEGIN
                set @tno=1
                insert into @AllRecords values(@DepartmentName,@deptt_code)
                fetch next from cur_FetchDepartmetName into
                @deptt_code,@DepartmentName
          END
      else
          BEGIN
                set @tno=@tno+1
                insert into @AllRecords values(@DepartmentName,@deptt_code)
                fetch next from cur_FetchDepartmetName into
                @deptt_code,@DepartmentName
          END

   END
        --CLOSE CURSOR
        CLOSE cur_FetchDepartmetName
        DEALLOCATE cur_FetchDepartmetName

  select department_name, department_code from @AllRecords

我不想回答这个解决方案有什么错误,而是想提供一个更好的解决方案。在这个例子中使用游标是完全没有必要的,没有它可以更容易地编写查询。这是一个简单的 INSERT..SELECT 语句和记录计数以设置 @tno 最后可以很容易地完成。

BEGIN

set @stYear = SUBSTRING(@yr,0,5);
set @cYear = SUBSTRING(@yr,6,4);

--CREATE DYNAMIC TABLE WITH COLs
DECLARE @AllRecords table
(
  department_name varchar(50),
  project_name varchar(100), --what's the use of this column?
  department_code varchar(4)
 );

INSERT INTO @AllRecords (department_code, department_name)
select deptt_code,deptt_name+'('+ RTRIM(LTRIM(deptt_short))+')' as dept_name from m_Department 
  where deptt_code in (select distinct department_code from t_Project_Details where district_id=@DistrictId
  and financial_year=@yr);


SELECT @tNo = COALESCE(@tno,0) + COUNT(*) FROM @AllRecords;

select department_name, department_code from @AllRecords;

END

请查看这篇关于游标以及如何避免游标的文章:

Cursors and How to Avoid Them

您的 SQL 查询如下:

  BEGIN
         DECLARE @ColName VARCHAR(20)= NULL, @Query VARCHAR(MAX)= NULL, @DepartmentName VARCHAR(50)= NULL, @deptt_code VARCHAR(4)= NULL, @DistrictId VARCHAR(4)= '0001', @Deptt_Id CHAR(4)= NULL, @stYear VARCHAR(4)= NULL, @cYear VARCHAR(4)= NULL, @yr VARCHAR(9)= '2017-2018', @tno INT;
         SET @stYear = SUBSTRING(@yr, 0, 5);
         SET @cYear = SUBSTRING(@yr, 6, 4);

--DECLARE & SET COUNTER
         DECLARE @counter INT;
         SET @counter = 1;

--CREATE DYNAMIC TABLE WITH COLs
         DECLARE @AllRecords TABLE
         (department_name VARCHAR(50),
          project_name    VARCHAR(100),
          department_code VARCHAR(4)
         );

--*** Declare Cursor
         DECLARE cur_FetchDepartmentName CURSOR READ_ONLY
         FOR
             SELECT deptt_code,
                    deptt_name+'('+RTRIM(LTRIM(deptt_short))+')' AS dept_name
             FROM m_Department
             WHERE deptt_code IN
             (
                 SELECT DISTINCT
                        department_code
                 FROM t_Project_Details
                 WHERE district_id = @DistrictId
                       AND financial_year = @yr
             );
         OPEN cur_FetchDepartmetName;
         FETCH NEXT FROM cur_FetchDepartmetName INTO @deptt_code, @DepartmentName;

--LOOP UNTIL RECORDS ARE AVAILABLE
         WHILE @@FETCH_STATUS = 0
             BEGIN
                 IF(@tno = 0)
                     BEGIN
                         SET @tno = 1;
                         INSERT INTO @AllRecords
                         (department_name,
                          department_code
                         )
                                SELECT @DepartmentName,
                                       @deptt_code;
                         FETCH NEXT FROM cur_FetchDepartmetName INTO @deptt_code, @DepartmentName;
                 END;
                     ELSE
                     BEGIN
                         SET @tno = @tno + 1;
                         INSERT INTO @AllRecords
                         (department_name,
                          department_code
                         )
                                SELECT @DepartmentName,
                                       @deptt_code;
                         FETCH NEXT FROM cur_FetchDepartmetName INTO @deptt_code, @DepartmentName;
                 END;
             END;
        --CLOSE CURSOR
         CLOSE cur_FetchDepartmetName;
         DEALLOCATE cur_FetchDepartmetName;

        select department_name, department_code from @AllRecords
     END;