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?
-
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. -
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 cetteINSERT...EXEC
interne dans unINSERT...SELECT
et résolvez ce problème. -
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 despGetSites
(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