游标返回意外结果

时间:2017-11-30 05:38:17

标签: sql-server cursor

我有以下sql代码,它的行为不符合预期。它似乎返回两个不同的数据集(不确定数据集是否是正确的解释),每个数据集都有一个记录而不是一个带有两个记录的数据集。

我的sql应该读取一个包含国家和跟踪号码的表格。如果我找到我要查询的国家,我会将跟踪号码返回到光标。在我的例子中,我的光标中有两个跟踪号码。然后我遍历sql以从几个表中获取信息,并将结果放入该跟踪号的一个记录中(该部分有效)。第二次它对第二个跟踪号做同样的事情,除了它似乎把第二个记录放在它自己的数据集中。我期待有两个记录的结果,但它似乎是两个单独的结果。有人可以帮助解释并提供可能的指导吗?

这是我的sql

DECLARE @cur_trk_link VARCHAR(50)
--Declare Cursor
DECLARE Student_Cursor CURSOR FOR 

--Select trk_link from cc_ptms for passed CC

SELECT trk_link FROM CC_PTMS WHERE cc = 'JA'


--opne cursor
OPEN Student_Cursor

--Fetch from Cursor
FETCH NEXT FROM Student_Cursor INTO @cur_trk_link

WHILE @@FETCH_STATUS = 0 

BEGIN

    --execute main function to create records
    SELECT Top 1 t.trk_link

         ,(SELECT track + ' ' + country_na FROM TT_DTL AS td WHERE td.[trk_link]=LEFT (t.[trk_link], 20)) AS TrainingTrackCountry 

          ,t.scn
          ,t.given_nm AS FirstName
          ,t.surname_nm AS LastName
          ,t.cc AS CC
          ,t.sex AS Sex
          ,t.grade AS Grade
          ,t.dob AS StudentDob
          ,t.marital_st AS MaritalStatus
          ,t.pob_cntry AS BirthCountry
          ,t.pob_city AS BirthCity
          ,CASE t.UScitizenship_CD
              WHEN 'H' THEN 'Holds'
              WHEN 'DNH' THEN 'Does Not Hold'
              ELSE ''
              END AS StuCitizenStatus

          ,p.pass_nbr as Passport#
         ,STUFF((SELECT ', ' + pass_nbr FROM VI AS v WHERE v.[trk_link]=t.[trk_link] FOR XML PATH('')),1 ,1 ,'') AS Visa#
           ,STUFF((SELECT ', ' + given_nm+' '+ surname_nm FROM PD AS p2 where p2.[trk_link]=t.[trk_link] FOR XML PATH('')),1 ,1 ,'') AS DependentName
           ,STUFF((SELECT ', ' + dep_rel FROM PD AS p2 WHERE p2.[trk_link]=t.[trk_link] FOR XML PATH('')),1 ,1 ,'') AS DependentRelationship
           ,STUFF((SELECT ', ' + Convert(VARCHAR, birth_dt) FROM PD AS p2 where p2.[trk_link]=t.[trk_link] FOR XML PATH('')),1 ,1 ,'') AS DependentDob
           ,STUFF((SELECT ', ' + CASE UScitizenship_CD   WHEN 'H' THEN 'Holds'
              WHEN 'DNH' THEN 'Does Not Hold'
              ELSE ''
              END FROM PD AS p2 WHERE p2.[trk_link]=t.[trk_link] FOR XML PATH('')),1 ,1 ,'') AS DepCitizenStatus


    from TP t
    Left outer join P p
    on t.[trk_link] = p.[trk_link]
    Left outer join PD p2 on t.[trk_link] = p2.[trk_link]

    WHERE t.trk_link = @cur_trk_link

    FETCH NEXT FROM Student_Cursor INTO @cur_trk_link

    END

    CLOSE  Student_Cursor
    DEALLOCATE  Student_Cursor'

有人可以协助吗?谢谢佩内洛普

[结果样本]

enter image description here

1 个答案:

答案 0 :(得分:0)

在循环中执行select语句。每次执行时,它都会生成1行的结果集。如果您的目标是生成包含“匹配”的所有行的1个结果集,则需要将它们临时存储在表(permanent,temp或variable)中。但是根据您发布的内容,您根本不需要光标。将where子句替换为“where t.trk_lnk in(this cursor query here)”。也许还可以添加order by子句。

如果您打算使用光标,请仔细考虑为什么需要使用“select top 1”。就像“不同”一样,这种用法通常是隐藏逻辑上有缺陷的查询的一种方法。并且使用没有order by子句的“select top x”在逻辑上是有缺陷的,因为不能保证选择哪一行(多个)。