2017-11-30 5 views
0

다음 SQL 코드가 있으며 예상대로 작동하지 않습니다. 그것은 두 개의 다른 데이터 세트를 반환하는 것으로 보인다. (데이터 세트가 올바른지 확실하지 않다.) 두 개의 레코드가있는 하나의 데이터 셋 대신에 각각 레코드가있다.커서가 예기치 않은 결과를 반환합니다.

My 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' 

누군가가 도움을 줄 수있다? 감사합니다 페넬로페

[결과의 샘플]는 SELECT 문을 실행할 루프에서

enter image description here

답변

0

. 실행될 때마다 1 행의 결과 집합이 생성됩니다. 목표가 "일치하는"행을 모두 포함하는 결과 세트를 생성하는 것이라면 테이블 (영구, 임시 또는 변수)에 임시로 저장해야합니다. 그러나 게시 한 내용에서 커서가 전혀 필요하지 않습니다. where 절을 "where t.trk_lnk in (여기서 커서 쿼리)"와 같이 바꿉니다. 그리고 order by 절도 추가 할 수 있습니다.

커서를 사용하려는 경우 "톱 1 선택"을 사용해야하는 이유를 신중하게 고려하십시오. "distinct"처럼,이 사용법은 종종 논리적으로 결함이있는 쿼리를 숨기기위한 절박한 행동입니다. order by 절을 사용하지 않고 "select top x"를 사용하면 논리적으로 결함이 있습니다. 이는 많은 행 중에서 어떤 것이 선택되었는지 보장 할 수 없기 때문입니다.

+0

감사합니다. 임시 테이블이 있어야합니다. :) –