Sql server 游标逻辑错误

Sql server 游标逻辑错误,sql-server,Sql Server,我编写这个SP是为了存储两个表中的数据,其中第二个表包含sectionID 我想把学生分配到他们的部门 ALTER PROC [dbo].[StudentDistribution] -- '6,7,8,9,10','1,2',1,1 ( @pUserID varchar(8000), @pSectionID varchar(8000), @pClassID int, @pModifiedBy int ) as DECLARE @Cntr int set @Cntr = (se

我编写这个SP是为了存储两个表中的数据,其中第二个表包含sectionID 我想把学生分配到他们的部门

ALTER PROC [dbo].[StudentDistribution] -- '6,7,8,9,10','1,2',1,1   
(
@pUserID varchar(8000),
@pSectionID varchar(8000),
@pClassID int,
@pModifiedBy int
)
as




DECLARE @Cntr int   
set @Cntr = (select count(*) from split(@pUserID,','))
select sum(Capacity) from SectionsClasses where ClassID=@pClassID and SectionID in (select vItem from split(@pSectionID,','))

DECLARE FetchStudent Cursor for
select vItem from split(@pUserID,',')

DECLARE @vUserID  int
DECLARE @vSecID int
DECLARE @vOut_Status int
DECLARE @vInner_Status int

        Open FetchStudent
        Fetch NEXT From FetchStudent into @vUserID
        set @vOut_Status= @@FETCH_STATUS 
        WHILE @vOut_Status = 0 

            begin 
            DECLARE FetchSection Cursor for
            select vItem from split(@pSectionID,',')

                OPEN FetchSection
                    Fetch NEXT From FetchSection into @vSecID
                    set @vInner_Status= @@FETCH_STATUS
                    WHILE @vInner_Status = 0 
                    begin

                    print(@vUserID)
                    print(@vSecID)


                    --IF @cntr <= 0
                    --  break
                    --else
                    --  set @Cntr=@Cntr-1



                    Fetch NEXT From FetchStudent into @vUserID
                    set @vOut_Status= @@FETCH_STATUS

                    Fetch NEXT From FetchSection into @vSecID
                    set @vInner_Status= @@FETCH_STATUS




                    END
                    Close FetchSection
                    Deallocate FetchSection

            --IF @cntr <= 0
            --          break
            --      else
            --          set @Cntr=@Cntr-1
            Fetch NEXT From FetchStudent into @vUserID

            END
    Close FetchStudent
    Deallocate FetchStudent
但我得到的是

6  1
7  2
9  1
10 2
有人能找出问题出在哪里吗?

这就是答案

 ALTER PROC [dbo].[StudentDistribution] --'6,7,8,9,10,11,12,13','1',3,1   
(
@pUserID varchar(8000),
@pSectionID varchar(8000),
@pClassID int,
@pModifiedBy int    
)
as



DECLARE @vCntr int  
DECLARE @vCapacity int 

set @vCntr = (select count(*) from split(@pUserID ,','))
select  @vCapacity = sum(Capacity) from SectionsClasses where ClassID=@pClassID and SectionID in (select vItem from split(@pSectionID,','))

    if @vCntr >  @vCapacity
    BEGIN
        print('Operation cannot complete; the number of student exceeds capacity')
            Return
    END

DECLARE FetchStudent Cursor  SCROLL for
select vItem from split(@pUserID,',')

DECLARE @vUserID  int
DECLARE @vSecID int
DECLARE @vOut_Status int
DECLARE @vInner_Status int

        Open FetchStudent
        Fetch NEXT From FetchStudent into @vUserID
        set @vOut_Status= @@FETCH_STATUS 
        WHILE (@vOut_Status = 0 )

            begin 
            DECLARE FetchSection Cursor  SCROLL for
            select vItem from split(@pSectionID,',')

                OPEN FetchSection
                    Fetch NEXT From FetchSection into @vSecID
                    set @vInner_Status= @@FETCH_STATUS
                    WHILE (@vInner_Status = 0 )
                    BEGIN

                    print(@vUserID)
                    print(@vSecID)


                    Fetch NEXT From FetchSection into @vSecID
                    set @vInner_Status= @@FETCH_STATUS
                    --IF @vInner_Status = -1
                    --      BREAK
                    Fetch NEXT From FetchStudent into @vUserID
                    set @vOut_Status= @@FETCH_STATUS 
                        IF @vOut_Status = -1
                            BREAK


                    END

                    Close FetchSection
                    Deallocate FetchSection



            IF @vInner_Status =-1
            Fetch PRIOR From FetchStudent into @vUserID

            Fetch NEXT From FetchStudent into @vUserID
            set @vOut_Status= @@FETCH_STATUS

            END
    Close FetchStudent
    Deallocate FetchStudent

这是你的光标的替代品:

WITH sections AS (
  SELECT
    x.ID,
    RN = ROW_NUMBER() OVER (ORDER BY x.ID)
  FROM dbo.split(@pSectionID, ',') AS f
  CROSS APPLY (SELECT CAST(f.vItem AS int)) AS x (ID)
),
users AS (
  SELECT
    x.ID,
    SectionRN = NTILE((SELECT COUNT(*) FROM sections)) OVER (ORDER BY x.ID)
  FROM dbo.split(@pUserID, ',') AS f
  CROSS APPLY (SELECT CAST(f.vItem AS int)) AS x (ID)
)
SELECT
  UserID    = u.ID,
  SectionID = s.ID
FROM users AS u
INNER JOIN sections AS s ON u.SectionRN = s.RN
;
对于
@pUserID
作为
'6,7,8,9,10'
pSectionID
作为
'1,2'
,上述将返回如下结果集:

UserID  SectionID
------  ---------
6       1
7       1
8       1
9       2
10      2
UserID  SectionID
------  ---------
6       1
7       2
8       1
9       2
10      1
如果你坚持这样的结果:

UserID  SectionID
------  ---------
6       1
7       1
8       1
9       2
10      2
UserID  SectionID
------  ---------
6       1
7       2
8       1
9       2
10      1
users
中的
部分rn
计算更改为:

SectionRN = (ROW_NUMBER() OVER (ORDER BY x.ID) - 1) % (SELECT COUNT(*) FROM sections) + 1

有用的阅读:


我承认,我很难阅读光标,因为我从不写它们。我想你要做的是给一个表一个SectionID,然后给一个学生列表一个逗号分隔的列表,把学生列表分解成一行,让他们每个功能都在一行上?请确认您试图实现的目标,而不是光标试图实现的目标,并请添加您的数据结构和一些示例数据,以帮助我们帮助您。我有逗号分隔列表中的学生列表和逗号分隔列表中的章节列表,我使用了split函数,返回表包含vItem属性,这是一个列表,但在每一行中,我想做的是将来自split的部分表分配到student表中,为什么不能使用基于集合的方法呢?什么是基于集合的@FreshPrinceOfSO???