Hoy en día, una consulta necesita devolver un conjunto de resultados a través de ExcuteReader y, al mismo tiempo, quiere generar parámetros. Al principio, no pude obtener el valor de los parámetros de salida, pensando que el procedimiento almacenado tenía un error. la prueba en el analizador de consultas fue correcta y los parámetros de salida efectivamente se cambiaron.
Lo que es aún más desconcertante es que después de generar una excepción durante la conversión de tipo forzada de la salida, se puede obtener nuevamente. ¿Es imposible imaginar una página así? Aparece la API más utilizada. ¿Es esto incorrecto? Mi código es similar al siguiente escenario:
intente {
usando (SqlDataReader dr = cmd.ExecuteReader(CommandBehavior.CloseConnection)) {
int val = (int)cmd.Parameters[1].Value // Todavía vacío ahora
// más
}
}
captura (Excepción exp) {
throw new ApplicationException("Valor del parámetro de salida: " + cmd.Parameters[1].Value, exp // Ahora se puede obtener el valor de salida);
}
Es realmente frustrante. Después de depurar y rastrear durante una hora,
finalmente encontré la respuesta en MSDN:
Cuando utiliza un objeto Command con un procedimiento almacenado, puede establecer la propiedad CommandType del objeto Command en StoredProcedure. Cuando CommandType es StoredProcedure, puede utilizar la propiedad Parámetros del comando para acceder a los parámetros de entrada y salida y a los valores de retorno. Independientemente del método Execute que se llame, se puede acceder a la propiedad Parámetros. Sin embargo, cuando se llama a ExecuteReader, no se podrá acceder al valor de retorno y a los parámetros de salida hasta que se cierre DataReader.
ref: http://msdn2.microsoft.com/zh-CN/library/tyy0sz6b.aspx
Eso es todo. Siento que la EM me ha engañado otra vez, ¿por qué no tengo experiencia en el aprendizaje? Ya modifiqué el documento y
volví a él. Aún se puede explicar su propio entorno de código.
Porque cuando se detecta la excepción, el alcance de uso se salta, el DataReader se cierra automáticamente y, naturalmente, se puede obtener el valor del parámetro de salida.
Por supuesto, si pones el try catch en uso, aún no podrás obtenerlo, porque todavía está en el alcance del uso y el DataReader no se ha cerrado.
Además, MSDN dice que sólo se puede acceder a él si el DataReader está cerrado, pero no es así.
Después de las pruebas, se puede resumir de la siguiente manera:
1. Para ExecuteReader, el parámetro de salida y el valor de retorno se devuelven a DataReader como un conjunto de resultados, y el conjunto de resultados es siempre el último.
2. Según 1, cuando hay un conjunto de resultados, para acceder a los parámetros de salida y los valores de retorno, debe llamar a NextResult a la ubicación del conjunto de resultados correspondiente a los parámetros de salida y los valores de retorno.
3. Según 1, cuando Execute no devuelve un conjunto de resultados, se puede acceder a él directamente (tenga en cuenta que no es necesario llamar a Read())
4. Preste especial atención a la necesidad de llamar a NextResult varias veces si se devuelven varios conjuntos de resultados, si el número de conjuntos de resultados es dinámico, entonces el valor de retorno de nextResult() es falso.
5. Incluso si se especifica la opción CommandBehavior.SingleResult para ExecuteReader (que devuelve un único conjunto de resultados; de hecho, devuelve el primer conjunto de resultados del lote), los parámetros de salida se devuelven como un conjunto de resultados.
6. Al cerrar DataReader (Close()), los parámetros de salida se completan y, por lo tanto, se pueden acceder a ellos.
7. Dado que DataReader es solo de lectura directa, incluso si los parámetros de salida se obtienen a través del método NextResult antes de cerrar DataReader, ya no se puede acceder al conjunto de resultados anterior (en algunos casos, es posible que desee controlar dinámicamente el conjunto de resultados a través de la salida). parámetros de visita).
8. Para resolver el problema en 6, no puede usar el parámetro de salida y devolver directamente el parámetro de salida como primer resultado (SELECT @parmname).
Lo anterior es solo mi propio resumen, espero que no haya discrepancias. útil para principiantes.
árbitro:
http://www.bigcircleboy.net/583a194f-2c2c-4662-9036-4e2f0eb262396084313157728108.html