Ho un proc spGetSites memorizzato che restituisce tre colonne per SiteName, SiteId e UnitCount. Il processo memorizzato funziona perfettamente. Sto cercando di memorizzare i risultati della procedura memorizzata in una tabella temporanea @Site da utilizzare per il mio rapporto con la sintassi seguente. Questa volta ho ricevuto un messaggio di errore: “Listruzione INSERT EXEC non può essere annidata”

Non posso utilizzare le istruzioni INSERT e EXEC contemporaneamente?

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

Commenti

  • Dovresti , dbfiddle.uk/… Aggiungi la procedura memorizzata alla domanda e tagga la tua versione di SQL Server.

Risposta

Se guardi il codice del tuo spGetSites , da qualche parte in quella procedura cè un altro INSERT...EXEC. Potrebbe essere direttamente in quella procedura, o annidato nelle viscere di qualche altra procedura che chiama.

In definitiva, se una procedura memorizzata utilizza INSERT...EXEC, se provi a chiamare quella procedura memorizzata nel contesto di unaltra INSERT...EXEC riceverai lerrore che sei vedendo .

Come risolverlo?

  1. Potresti semplicemente prendere il INSERT...EXEC interno e incorporare il codice a questo procedura memorizzata unica. Tuttavia, sospetto che ci sia unaltra procedura per un motivo: ad esempio per mantenere il codice ASCIUTTO.

  2. Poiché questo è un Get, si spera che non avvenga alcuna manipolazione dei dati da nessuna parte nello stack di chiamate. È possibile convertire la procedura figlia in una funzione con valori di tabella. Ciò consentirebbe di convertire quella INSERT...EXEC interna in un INSERT...SELECT e risolvere il problema.

  3. Utilizza le tabelle temporanee con ambito per la procedura esterna per passare i dati tra le procedure. Questa soluzione ottiene complicato, quindi non è il mio preferito, e generalmente sconsiglio questo schema quando cè “unopzione migliore – ma per completezza, lo includerò qui. Fondamentalmente, se crei la tua tabella #temp allesterno di spGetSites puoi usarla allinterno di spGetSites (senza crearla allinterno) e la tabella con i dati inseriti sopravviverà allesecuzione della procedura e continuerà a funzionare.

Non mi piace lopzione 3 perché è uno schema di codifica abbastanza complesso da garantire che qualcuno lo incasini in futuro, a meno che tutti non siano daccordo e abbiano familiarità con la codifica pattern: * spGetSites non funzionerà a meno che non crei prima la tabella. Tutti i chiamanti devono ricordarsi di creare prima la tabella esattamente la stessa. * spGetSites non può “presumere che la tabella sia vuota. Potrebbe avere dati esistenti dalla chiamata esterna (o unesecuzione precedente dallo stesso chiamante) * Risoluzione dei problemi e debug (e persino ottenere un piano di query) per spGetSites è più complesso a causa della confusione nella creazione della tabella.

Cosa dovrei fare?

Senza sapere quanto sia complesso il il codice è dietro spGetSites, vorrei “creare un TVF inline che sostituisca il INSERT...EXEC interno con INSERT...SELECT o possibilmente tutto spGetSites potrebbe essere semplificato / riscritto per renderlo autonomo senza INSERT...EXEC

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *