Am un proc spGetSites stocat care returnează trei coloane pentru SiteName, SiteId și UnitCount. Proc stocat funcționează perfect. „Încerc să stochez rezultatele procesului stocat într-un tabel temporar @Site pentru a-l folosi pentru raportul meu cu sintaxa de mai jos. De data aceasta am primit un mesaj de eroare:” Instrucțiunea INSERT EXEC nu poate fi imbricată „

Nu pot folosi instrucțiunea INSERT și EXEC în același timp?

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

Comentarii

  • Ar trebui , dbfiddle.uk/… Vă rugăm să adăugați procedura stocată la întrebare și etichetați versiunea SQL Server.

Răspuns

Dacă te uiți la codul pentru spGetSites procedura, undeva în această procedură este un alt INSERT...EXEC. Poate fi direct în această procedură sau cuibărit în intestinele altei proceduri pe care le numește.

În cele din urmă, dacă o procedură stocată folosește INSERT...EXEC atunci dacă încercați să apelați această procedură stocată în contextul altei INSERT...EXEC veți primi eroarea văzând .

Cum o remediați?

  1. Puteți pur și simplu să luați INSERT...EXEC interior și să introduceți codul în acest sens singură procedură stocată. Totuși, bănuiesc că ar putea exista o altă procedură dintr-un motiv: adică să păstrezi codul DRY.

  2. Deoarece acesta este un Get procedură, sperăm că nu există manipulări de date nicăieri în stiva de apeluri. Puteți converti procedura copil într-o funcție cu valoare de tabel. Acest lucru vă va permite să convertiți acea INSERT...EXEC într-un INSERT...SELECT și rezolvați această problemă.

  3. Utilizați tabele temp cu scop la procedura externă pentru a transmite date între proceduri. Această soluție primește complicat, deci nu este preferatul meu și, în general, descurajez acest tipar atunci când există o opțiune mai bună – dar, din motive de completitudine, îl voi include aici. Practic, dacă creați tabelul #temp în afara spGetSites îl puteți utiliza în interiorul spGetSites (fără a-l crea în interiorul acestuia) și al tabelului cu datele inserate va supraviețui executării procedurii și va continua să funcționeze.

Nu-mi place opțiunea 3, deoarece este un model de codare suficient de complex pentru a asigura că cineva o încurcă în viitor, cu excepția cazului în care toată lumea este la bord și este familiarizată cu codarea model: * spGetSites va eșua dacă nu creați mai întâi tabelul. Toți apelanții trebuie să-și amintească pentru a crea tabelul exact la fel mai întâi. * spGetSites nu poate presupune că tabelul este gol. Este posibil să aibă date existente din apelul extern (sau o execuție anterioară de la același apelant) * Depanare și depanare (și chiar obținerea unui plan de interogare) pentru spGetSites este mai complex din cauza confuziei de creare a tabelelor.

Ce aș face?

Fără a ști cât de complex este codul se află în spatele spGetSites, aș căuta să creez un TVF în linie care să înlocuiască INSERT...EXEC interior cu INSERT...SELECT sau, eventual, toate spGetSites ar putea fi simplificate / rescrise pentru a fi conținute în sine fără INSERT...EXEC

Lasă un răspuns

Adresa ta de email nu va fi publicată. Câmpurile obligatorii sunt marcate cu *