Acceso a conjuntos de resultados desde procedimientos almacenados Transact-SQL SQL Server

StackOverflow https://stackoverflow.com/questions/58940

  •  09-06-2019
  •  | 
  •  

Pregunta

Estoy usando SQL Server 2005 y me gustaría saber cómo acceder a diferentes conjuntos de resultados desde transact-sql.El siguiente procedimiento almacenado devuelve dos conjuntos de resultados, ¿cómo accedo a ellos desde, por ejemplo, otro procedimiento almacenado?

CREATE PROCEDURE getOrder (@orderId as numeric) AS
BEGIN   
    select order_address, order_number from order_table where order_id = @orderId
    select item, number_of_items, cost from order_line where order_id = @orderId
END

Necesito poder recorrer ambos conjuntos de resultados individualmente.

EDITAR:Sólo para aclarar la pregunta, quiero probar los procedimientos almacenados.Tengo un conjunto de procedimientos almacenados que se utilizan desde un cliente VB.NET y que devuelven múltiples conjuntos de resultados.Estos no se cambiarán a una función con valores de tabla; de hecho, no puedo cambiar los procedimientos en absoluto.Cambiar el procedimiento no es una opción.

Los conjuntos de resultados devueltos por los procedimientos no son los mismos tipos de datos o número de columnas.

¿Fue útil?

Solución

La respuesta corta es:no puedes hacerlo.

Desde T-SQL no hay forma de acceder a múltiples resultados de una llamada a un procedimiento almacenado anidado, sin cambiar el procedimiento almacenado como han sugerido otros.

Para completar, si el procedimiento devolviera un único resultado, podría insertarlo en una tabla temporal o variable de tabla con la siguiente sintaxis:

INSERT INTO #Table (...columns...)
EXEC MySproc ...parameters...

Puede usar la misma sintaxis para un procedimiento que devuelve múltiples resultados, pero solo procesará el primer resultado, el resto se descartará.

Otros consejos

Pude hacer esto fácilmente creando un procedimiento almacenado CLR SQL2005 que contenía un conjunto de datos interno.

Verá, un nuevo SqlDataAdapter completará un sproc de conjunto de resultados múltiples en un conjunto de datos de múltiples tablas de forma predeterminada.Los datos de estas tablas, a su vez, se pueden insertar en tablas #Temp en el proceso de llamada que desea escribir. conjunto de datos.ReadXmlSchema le mostrará el esquema de cada conjunto de resultados.

Paso 1:Comience a escribir el sproc que leerá los datos del sproc del conjunto de resultados múltiples

a.Cree una tabla separada para cada conjunto de resultados según el esquema.

CREATE PROCEDURE [dbo].[usp_SF_Read] AS
SET NOCOUNT ON;
CREATE TABLE #Table01 (Document_ID VARCHAR(100)
  , Document_status_definition_uid INT
  , Document_status_Code VARCHAR(100) 
  , Attachment_count INT
  , PRIMARY KEY (Document_ID));

b.En este punto, es posible que necesites declarar un cursor para llamar repetidamente al proceso CLR que crearás aquí:

Paso 2:Hacer el CLR Sproc

Partial Public Class StoredProcedures
    <Microsoft.SqlServer.Server.SqlProcedure()> _
    Public Shared Sub usp_SF_ReadSFIntoTables()

    End Sub
End Class

a.Conéctate usando New SqlConnection("context connection=true").

b.Configure un objeto de comando (cmd) para contener el sproc de conjunto de resultados múltiples.

C.Obtenga todos los datos usando lo siguiente:

    Dim dataset As DataSet = New DataSet
    With New SqlDataAdapter(cmd)
        .Fill(dataset) ' get all the data.
    End With
'you can use dataset.ReadXmlSchema at this point...

d.Repita cada tabla e inserte cada fila en la tabla temporal adecuada (que creó en el paso uno anterior).

Nota final:En mi experiencia, es posible que desee imponer algunas relaciones entre sus tablas para saber de qué lote proviene cada registro.

¡Eso es todo lo que había que hacer!

~ Shaun, cerca de Seattle

Hay una pifia que tú también puedes hacer.Agregue un parámetro opcional N int a su sproc.El valor predeterminado de N es -1.Si el valor de N es -1, entonces haz cada una de tus selecciones.De lo contrario, haga la enésima selección y solo la enésima selección.

Por ejemplo,

if (N = -1 or N = 0)
    select ...

if (N = -1 or N = 1)
    select ...

Las personas que llaman a su sproc y que no especifican N obtendrán un conjunto de resultados con más de una tabla.Si necesita extraer una o más de estas tablas de otro sproc, simplemente llame a su sproc especificando un valor para N.Tendrás que llamar al sproc una vez para cada tabla que desees extraer.Ineficiente si necesita más de una tabla del conjunto de resultados, pero funciona en TSQL puro.

Tenga en cuenta que existe una limitación adicional no documentada para INSERTAR EN...Declaración EXEC:no se puede anidar.Es decir, el proceso almacenado que llama el EXEC (o cualquiera que llame a su vez) no puede hacer un INSERT INTO...EJECUTIVO.Parece que hay un único bloc de notas por proceso que acumula el resultado y, si están anidados, obtendrá un error cuando la persona que llama lo abre y luego el destinatario intenta abrirlo nuevamente.

Matthieu, necesitarías mantener tablas temporales separadas para cada "tipo" de resultado.Además, si ejecuta el mismo proceso varias veces, es posible que deba agregar una columna adicional a ese resultado para indicar de qué llamada resultó.

Lamentablemente es imposible hacer esto.El problema es, por supuesto, que no existe una sintaxis SQL que lo permita.Sucede "debajo del capó", por supuesto, pero no se pueden obtener estos otros resultados en TSQL, sólo desde la aplicación a través de ODBC o lo que sea.

Hay una manera de evitarlo, como ocurre con la mayoría de las cosas.El truco consiste en utilizar la automatización antigua en TSQL para crear un objeto ADODB que abra cada conjunto de resultados por turno y escriba los resultados en las tablas que usted designe (o haga lo que quiera con los conjuntos de resultados).También puedes hacerlo en DMO si disfrutas del dolor.

Hay dos formas de hacer esto fácilmente.Pegue los resultados en una tabla temporal y luego haga referencia a la tabla temporal de su sproc.La otra alternativa es poner los resultados en una variable XML que se utiliza como variable de SALIDA.

Sin embargo, ambas opciones tienen ventajas y desventajas.Con una tabla temporal, deberá agregar código al script que crea el procedimiento de llamada para crear la tabla temporal antes de modificar el procedimiento.Además, debes limpiar la tabla temporal al final del procedimiento.

Con XML, puede consumir mucha memoria y ser lento.

Puede seleccionarlos en tablas temporales o escribir funciones con valores de tabla para devolver conjuntos de resultados.¿Se preguntan cómo iterar a través de los conjuntos de resultados?

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top