Accès aux jeux de résultats à partir des procédures stockées Transact-SQL SQL Server

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

  •  09-06-2019
  •  | 
  •  

Question

J'utilise SQL Server 2005 et j'aimerais savoir comment accéder à différents jeux de résultats à partir de transact-sql.La procédure stockée suivante renvoie deux jeux de résultats. Comment puis-je y accéder à partir, par exemple, d'une autre procédure stockée ?

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

Je dois être capable de parcourir les deux ensembles de résultats individuellement.

MODIFIER:Juste pour clarifier la question, je souhaite tester les procédures stockées.J'ai un ensemble de procédures stockées utilisées à partir d'un client VB.NET, qui renvoient plusieurs jeux de résultats.Celles-ci ne vont pas être modifiées en fonction table, je ne peux en fait pas du tout changer les procédures.Changer la procédure n’est pas une option.

Les jeux de résultats renvoyés par les procédures ne correspondent pas aux mêmes types de données ni au même nombre de colonnes.

Était-ce utile?

La solution

La réponse courte est :tu ne peux pas le faire.

À partir de T-SQL, il n'existe aucun moyen d'accéder à plusieurs résultats d'un appel de procédure stockée imbriquée, sans modifier la procédure stockée comme d'autres l'ont suggéré.

Pour être complet, si la procédure renvoyait un seul résultat, vous pourriez l'insérer dans une table temporaire ou une variable de table avec la syntaxe suivante :

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

Vous pouvez utiliser la même syntaxe pour une procédure qui renvoie plusieurs résultats, mais elle ne traitera que le premier résultat, le reste sera ignoré.

Autres conseils

J'ai pu facilement le faire en créant une procédure stockée SQL2005 CLR contenant un ensemble de données interne.

Vous voyez, un nouveau SqlDataAdapter remplira par défaut une procédure à ensembles de résultats multiples dans un ensemble de données à plusieurs tables.Les données de ces tables peuvent à leur tour être insérées dans les tables #Temp de la procédure appelante que vous souhaitez écrire. ensemble de données.ReadXmlSchema vous montrera le schéma de chaque ensemble de résultats.

Étape 1:Commencez à écrire le sproc qui lira les données du sproc multi-résultats

un.Créez un tableau distinct pour chaque ensemble de résultats selon le schéma.

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.À ce stade, vous devrez peut-être déclarer un curseur pour appeler de manière répétitive la procédure CLR que vous allez créer ici :

Étape 2:Créer le Sproc CLR

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

    End Sub
End Class

un.Connectez-vous en utilisant New SqlConnection("context connection=true").

b.Configurez un objet de commande (cmd) pour contenir le sproc à plusieurs résultats.

c.Obtenez toutes les données en utilisant les éléments suivants :

    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.Parcourez chaque table et insérez chaque ligne dans la table temporaire appropriée (que vous avez créée à la première étape ci-dessus).

Remarque finale :D'après mon expérience, vous souhaiterez peut-être imposer certaines relations entre vos tables afin de savoir de quel lot provient chaque enregistrement.

C'est tout ce qu'il y avait à faire !

~ Shaun, près de Seattle

Il y a une astuce que vous pouvez aussi faire.Ajoutez un paramètre facultatif N int à votre sproc.Par défaut, la valeur de N est -1.Si la valeur de N est -1, effectuez chacune de vos sélections.Sinon, effectuez la Nième sélection et seulement la Nième sélection.

Par exemple,

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

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

Les appelants de votre sproc qui ne spécifient pas N obtiendront un jeu de résultats avec plusieurs tables.Si vous devez extraire une ou plusieurs de ces tables d'un autre sproc, appelez simplement votre sproc en spécifiant une valeur pour N.Vous devrez appeler le sproc une fois pour chaque table que vous souhaitez extraire.Inefficace si vous avez besoin de plus d'une table du jeu de résultats, mais cela fonctionne en TSQL pur.

Notez qu'il existe une limitation supplémentaire non documentée à INSERT INTO...Déclaration EXEC :il ne peut pas être imbriqué.Autrement dit, le processus stocké que l'EXEC appelle (ou celui qu'il appelle à son tour) ne peut pas effectuer lui-même un INSERT INTO ...EXÉC.Il semble qu'il y ait un seul bloc-notes par processus qui accumule le résultat, et s'ils sont imbriqués, vous obtiendrez une erreur lorsque l'appelant l'ouvrira, puis l'appelé essaiera de l'ouvrir à nouveau.

Matthieu, vous devrez conserver des tables temporaires distinctes pour chaque "type" de résultat.De plus, si vous exécutez le même plusieurs fois, vous devrez peut-être ajouter une colonne supplémentaire à ce résultat pour indiquer de quel appel il résulte.

Malheureusement, il est impossible de le faire.Le problème est bien sûr qu’il n’existe pas de syntaxe SQL pour le permettre.Cela se produit bien sûr « sous le capot », mais vous ne pouvez pas obtenir ces autres résultats dans TSQL, uniquement à partir de l'application via ODBC ou autre.

Il existe un moyen de contourner ce problème, comme pour la plupart des choses.L'astuce consiste à utiliser ole automation dans TSQL pour créer un objet ADODB qui ouvre chaque jeu de résultats tour à tour et écrit les résultats dans les tables que vous nommez (ou faites ce que vous voulez avec les jeux de résultats).vous pouvez également le faire en DMO si vous aimez la douleur.

Il existe deux façons de procéder facilement.Soit collez les résultats dans une table temporaire, puis référencez la table temporaire à partir de votre sproc.L'autre alternative consiste à placer les résultats dans une variable XML utilisée comme variable OUTPUT.

Il y a cependant des avantages et des inconvénients à ces deux options.Avec une table temporaire, vous devrez ajouter du code au script qui crée la procédure appelante pour créer la table temporaire avant de modifier la procédure.Vous devez également nettoyer la table temporaire à la fin de la procédure.

Avec le XML, cela peut être gourmand en mémoire et lent.

Vous pouvez les sélectionner dans des tables temporaires ou écrire des fonctions table pour renvoyer des ensembles de résultats.Vous demandez comment parcourir les ensembles de résultats ?

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top