Jai un proc spGetSites stocké qui renvoie trois colonnes pour SiteName, SiteId et UnitCount. Le processus stocké fonctionne parfaitement. Jessaye de stocker les résultats du processus stocké dans une table temporaire @Site à utiliser pour mon rapport avec la syntaxe ci-dessous. Cette fois, jai reçu un message derreur: « Linstruction INSERT EXEC ne peut pas être imbriquée »

Puis-je ne pas utiliser les instructions INSERT et EXEC en même temps?

DECLARE @Site TABLE (SiteName VARCHAR(100), SiteId INT, UnitCount INT) INSERT INTO @Site EXEC spGetSites @SiteId = 0 

Commentaires

  • Vous devriez , dbfiddle.uk/… Veuillez ajouter votre procédure stockée à la question et baliser votre version de SQL Server.

Réponse

Si vous regardez le code de votre spGetSites procédure, quelque part dans cette procédure se trouve une autre INSERT...EXEC. Elle peut être directement dans cette procédure, ou imbriquée dans les entrailles dune autre procédure quelle appelle.

En fin de compte, si une procédure stockée utilise INSERT...EXEC, si vous essayez dappeler cette procédure stockée dans le contexte dun autre INSERT...EXEC, vous obtiendrez lerreur que vous êtes voyant .

Comment y remédier?

  1. Vous pouvez simplement prendre le INSERT...EXEC intérieur et insérer le code à celui-ci procédure stockée unique. Cependant, je soupçonne quune autre procédure peut être là pour une raison: cest-à-dire pour garder votre code SEC.

  2. Puisquil sagit dun Get procédure, jespère quaucune manipulation de données ne se produit dans la pile dappels. Vous pouvez convertir la procédure enfant en une fonction table. Cela vous permettrait de convertir cette INSERT...EXEC interne dans un INSERT...SELECT et résolvez ce problème.

  3. Utilisez des tables temporaires étendues à la procédure externe pour transmettre des données entre les procédures. Cette solution obtient compliqué, donc ce nest pas mon préféré, et je déconseille généralement ce modèle quand il ya une meilleure option – mais par souci dexhaustivité, je vais linclure ici. Fondamentalement, si vous créez votre table #temp en dehors de spGetSites vous pouvez lutiliser à lintérieur de spGetSites (sans la créer à lintérieur), et la table avec les données insérées survivra à lexécution de la procédure et continuera à fonctionner.

Je naime pas loption 3 car cest un modèle de codage suffisamment complexe pour que quelquun le gâche à lavenir, à moins que tout le monde ne soit à bord et familiarisé avec le codage pattern: * spGetSites échouera sauf si vous créez dabord la table. Tous les appelants doivent se rappeler de créer la table exactement de la même manière en premier. * spGetSites ne peut « t supposer que la table est vide. Elle peut contenir des données existantes de lappel externe (ou une exécution antérieure du même appelant) * Dépannage et débogage (et même obtenir un plan de requête) pour spGetSites est plus complexe en raison de la confusion de création de table.

Que ferais-je?

Sans savoir à quel point le le code est derrière spGetSites, j « envisagerais de créer un TVF en ligne qui remplace le INSERT...EXEC par INSERT...SELECT ou peut-être tout spGetSites pourrait être simplifié / réécrit pour le rendre autonome sans INSERT...EXEC

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *