현재 쿼리는 ExcuteReader를 통해 결과 집합을 반환해야 하며 동시에 매개 변수를 출력하려고 합니다. 처음에는 저장 프로시저에 오류가 있는 것으로 생각하여 출력 매개 변수의 값을 가져올 수 없었습니다. 쿼리 분석기의 테스트가 정확했고 출력 매개변수가 실제로 변경되었습니다.
더 의아스러운 점은 출력의 강제 유형 변환 중에 예외가 발생하면 실제로 다시 얻을 수 있다는 것입니다. ado.net의 버그인지는 그런 페이지를 상상하는 것이 불가능합니다. 일반적으로 사용되는 API가 잘못되었습니까? 내 코드는 다음 시나리오와 유사합니다
.
(SqlDataReader dr = cmd.ExecuteReader(CommandBehavior.CloseConnection))을 사용하여 {
int val = (int)cmd.Parameters[1].Value // 현재는 여전히 비어 있습니다.
// 더
}
}
catch(예외 exp) {
throw new ApplicationException("출력 매개변수 값: " + cmd.Parameters[1].Value, exp) // 이제 출력 값을 얻을 수 있습니다.
}
정말 실망스럽습니다. 한 시간 동안 디버깅하고 추적한 끝에
마침내 MSDN에서 답을 찾았습니다.
저장 프로시저와 함께 Command 개체를 사용하는 경우 Command 개체의 CommandType 속성을 StoredProcedure로 설정할 수 있습니다. CommandType이 StoredProcedure인 경우 명령의 매개변수 속성을 사용하여 입력 및 출력 매개변수와 반환 값에 액세스할 수 있습니다. 어떤 Execute 메서드가 호출되는지에 관계없이 매개변수 속성에 액세스할 수 있습니다. 그러나 ExecuteReader가 호출되면 DataReader가 닫힐 때까지 반환 값과 출력 매개 변수에 액세스할 수 없습니다.
ref: http://msdn2.microsoft.com/zh-CN/library/tyy0sz6b.aspx
그렇군요. 또 MS에 속은 듯한 느낌이 듭니다. 왜 나는 학습 경험이 부족한 걸까요? 이미 문서를 변경하고
다시 반환했습니다. 자신의 코드 환경을 계속 설명할 수 있습니다.
Exception이 발생하면 사용 범위가 벗어나고 DataReader가 자동으로 닫히고 출력 매개 변수의 값을 자연스럽게 얻을 수 있기 때문입니다.
물론, try catch를 using에 넣으면 여전히 그것을 얻을 수 없습니다. 왜냐하면 여전히 using 범위에 있고 DataReader가 닫히지 않았기 때문입니다.
또한, MSDN에서는 DataReader를 닫아야만 접근이 가능하다고 되어 있는데, 그렇지 않습니다.
테스트를 마친 후 다음과 같이 요약할 수 있습니다.
1. ExecuteReader의 경우 Output parm 및 returnvalue가 결과 집합으로 DataReader에 반환되며 결과 집합은 항상 마지막 집합입니다.
2. 1에 따르면 결과 집합이 있는 경우 출력 매개 변수 및 반환 값에 액세스하려면 출력 매개 변수 및 반환 값에 해당하는 결과 집합 위치로 NextResult를 호출해야 합니다.
3. 1에 따르면 Execute가 결과 집합을 반환하지 않는 경우 직접 액세스할 수 있습니다(Read()를 호출할 필요가 없음).
4. 여러 결과 집합이 반환되는 경우 NextResult를 여러 번 호출해야 한다는 점에 특히 주의하세요. 결과 집합 수가 동적이면 nextResult()의 반환 값은 false입니다.
5. ExecuteReader에 CommandBehavior.SingleResult 옵션을 지정하더라도(단일 결과 집합 반환, 실제로는 배치의 첫 번째 결과 집합 반환) 출력 매개 변수가 결과 집합으로 반환됩니다.
6. DataReader를 닫으면(Close()) 출력 매개변수가 채워지므로 액세스할 수 있습니다.
7. DataReader는 읽기 전용이므로 DataReader를 닫기 전에 NextResult 메서드를 통해 출력 매개 변수를 가져오더라도 더 이상 이전 결과 집합에 액세스할 수 없습니다(경우에 따라 출력을 통해 결과 집합을 동적으로 제어하려는 경우도 있음). 매개변수를 방문하세요).
8. 6의 문제를 해결하기 위해서는 출력 매개변수를 사용하지 않고 출력 매개변수를 첫 번째 결과(SELECT @parmname)로 직접 반환할 수
는 없습니다
.초보자에게 도움이 됩니다.
참조:
http://www.bigcircleboy.net/583a194f-2c2c-4662-9036-4e2f0eb262396084313157728108.html