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?

  1. 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.

  2. 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 innere INSERT...EXEC konvertieren in ein INSERT...SELECT und beheben Sie dieses Problem.

  3. 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 von spGetSites (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

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.