Ich habe einen gespeicherten Prozess spGetSites, der drei Spalten für SiteName, SiteId und UnitCount zurückgibt. Der gespeicherte Prozess läuft einwandfrei. Ich versuche, die Ergebnisse des gespeicherten Prozesses in einer temporären Tabelle @Site zu speichern, um sie für meinen Bericht mit der folgenden Syntax zu verwenden. Diesmal wurde die Fehlermeldung „INSERT EXEC-Anweisung kann nicht verschachtelt werden“
angezeigt Kann ich die Anweisungen INSERT und EXEC nicht gleichzeitig verwenden?
DECLARE @Site TABLE (SiteName VARCHAR(100), SiteId INT, UnitCount INT) INSERT INTO @Site EXEC spGetSites @SiteId = 0
Kommentare
- Sie sollten , dbfiddle.uk/… Bitte fügen Sie der Frage Ihre gespeicherte Prozedur hinzu und markieren Sie Ihre SQL Server-Version.
Antwort
Wenn Sie sich den Code für Ihre spGetSites
ansehen Prozedur, irgendwo in dieser Prozedur befindet sich eine andere INSERT...EXEC
. Sie kann sich direkt in dieser Prozedur befinden oder im Darm einer anderen Prozedur verschachtelt sein, die sie aufruft.
Letztendlich Wenn eine gespeicherte Prozedur INSERT...EXEC
verwendet, wird der Fehler angezeigt, wenn Sie versuchen, diese gespeicherte Prozedur im Kontext einer anderen INSERT...EXEC
aufzurufen Sehen .
Wie können Sie das Problem beheben?
-
Sie können einfach die innere
INSERT...EXEC
verwenden und den Code darauf einfügen einzelne gespeicherte Prozedur. Ich vermute jedoch, dass eine andere Prozedur aus einem Grund vorhanden sein könnte: z. B. um Ihren Code trocken zu halten. -
Da dies eine
Get
Prozedur, hoffentlich findet nirgendwo im Aufrufstapel eine Datenmanipulation statt. Sie könnten die untergeordnete Prozedur in eine Funktion mit Tabellenwert konvertieren. Auf diese Weise können Sie diese innereINSERT...EXEC
konvertieren in einINSERT...SELECT
und beheben Sie dieses Problem. -
Verwenden Sie temporäre Tabellen für die äußere Prozedur, um Daten zwischen Prozeduren zu übertragen. Diese Lösung wird abgerufen kompliziert, also ist es nicht mein Favorit, und ich rate generell von diesem Muster ab, wenn es eine bessere Option gibt – aber der Vollständigkeit halber werde ich es hier aufnehmen. Wenn Sie Ihre # temp-Tabelle außerhalb von
spGetSites
erstellen, können Sie sie grundsätzlich innerhalb vonspGetSites
(ohne sie dort zu erstellen) und der Tabelle verwenden mit eingefügten Daten überlebt die Prozedurausführung und arbeitet weiter.
Ich mag Option 3 nicht, weil es ein Codierungsmuster ist, das komplex genug ist, um sicherzustellen, dass jemand es in Zukunft durcheinander bringt, es sei denn, jeder ist an Bord und mit der Codierung vertraut Muster: * spGetSites
schlägt fehl, es sei denn, Sie erstellen zuerst die Tabelle. Alle Anrufer müssen daran denken, die Tabelle zuerst genau gleich zu erstellen. * spGetSites
kann nicht davon ausgehen, dass die Tabelle leer ist. Möglicherweise sind Daten aus dem äußeren Aufruf (oder einer vorherigen Ausführung durch denselben Aufrufer) vorhanden. * Fehlerbehebung und Debugging (und sogar das Abrufen eines Abfrageplan) für spGetSites
ist aufgrund der Verwirrung bei der Tabellenerstellung komplexer.
Was würde ich tun?
Ohne zu wissen, wie komplex die Code steht hinter spGetSites
. Ich würde versuchen, eine Inline-TVF zu erstellen, die die innere INSERT...EXEC
durch INSERT...SELECT
oder möglicherweise alle spGetSites
könnten vereinfacht / umgeschrieben werden, um sie ohne die INSERT...EXEC
eigenständig zu machen div>