Comment réutiliser un résultat dans une procédure stockée pour alimenter un second select dans la même procédure stockée

J'écris une procédure stockée qui obtient des données pour un écran entier. Comment puis-je réutiliser le résultat d'une sélection pour l'introduire dans une seconde sélection? Ceci pour des raisons de performance

Exemple simplifié: j'ai 4 tables

  1. Responsable
  2. Action (a la key étrangère au responsable)
  3. Groupe (a la key étrangère à Responsable)
  4. Cas (a la key étrangère au groupe)

La procédure stockée obtient un cas pour récupérer datatables

La première sélection obtient les détails du case , du group et de son logging responsible associé:

 select Case.Date, Case.Name, Group.Name, Responsible.Name Responsible.ResponsibleID from Case inner join Group on Group.GroupID=Case.GroupID inner join Responsible on Responsible.ResponsibleID=Group.ResponsibleID where CaseID=@CaseID 

La seconde sélection doit get toutes les actions auxquelles le responsable est assigné. Nous avons seulement le caseID et donc nous devons rebuild les jointures:

 select Action.* from Case inner join Group on Group.GroupID=Case.GroupID inner join Responsible on Responsible.ResponsibleID=Group.ResponsibleID inner join Action on Action.ResponsibleID=Responsible.ResponsibleID where CaseID=@CaseID 

S'il serait possible de réutiliser la variable à partir du résultat précédent, il serait possible de créer la requête suivante qui serait probablement meilleure pour les performances:

 Select * from Action where ResponsibleID={ResultSet1}.ResponsibleID 

Pensez à conserver vos résultats dans une variable de table. Cela vous permettra d'effectuer plusieurs opérations SQL sur ce jeu de résultats à partir de vos tables permanentes.

 DECLARE @Case TABLE ( [CaseDate] datetime, [CaseName] varchar(100), [GroupName] varchar(100), [ResponsibleName] varchar(100), [ResponsibleID] int ) --get all your case details INSERT INTO @Case( [CaseDate],[CaseName], [GroupName],[ResponsibleName],[ResponsibleID]) SELECT Case.Date, Case.Name, Group.Name, Responsible.Name Responsible.ResponsibleID FROM Case INNER JOIN Group ON Group.GroupID=Case.GroupID INNER JOIN Responsible ON Responsible.ResponsibleID=Group.ResponsibleID WHERE CaseID=@CaseID --now get the Action details for the previous case; --are we absolutely sure there is only one row? then an INNER JOIN SELECT A.* FROM Action AS [A] INNER JOIN @Case AS C ON A.ResponsibleID=C.ResponsibleID -- or guard against multiple results in @Case SELECT A.* FROM Action AS [A] WHERE A.ResponsibleID = (SELECT TOP 1 ResponsibleID FROM @Case) 

Si vous obtenez des données pour différentes parties de l'écran en même time, lancez une seule requête. Oui – vous obtiendrez les mêmes données dans les colonnes principales, mais c'est le compromis contre le fait d'aller deux fois au server de database.

 select [Case].Date, [Case].Name CaseName, [Group].Name GroupName, Responsible.Name ResponsibleName, Responsible.ResponsibleID, Action.* from [Case] inner join [Group] on [Group].GroupID=[Case].GroupID inner join Responsible on Responsible.ResponsibleID=[Group].ResponsibleID inner join Action on Action.ResponsibleID=Responsible.ResponsibleID where [Case].CaseID=@CaseID 

D'autres choses que j'ai remarquées à propos de votre requête

  • Case est un mot réservé. Utilisez un nom différent, mais je pense que ce n'est pas le vrai nom de la table
  • Le groupe est aussi un mot réservé.
  • Le nom apparaît plusieurs fois dans la clause SELECT. Les alias de sorte que l'extrémité avant puisse y accéder de manière prévisible, au lieu d'utiliser la position de la colonne
  • Si nous fusionnons les requêtes, assurez-vous de listr (et alias si nécessaire) les colonnes d' Action.* Afin de ne pas entrer en conflit avec les autres colonnes