Jeg har en lagret proc spGetSites som returnerer tre kolonner for SiteName, SiteId og UnitCount. Den lagrede prosessen går helt greit. Jeg prøver å lagre resultatene av den lagrede proc til en temp-tabell @ Site for å bruke for rapporten min med syntaksen nedenfor. Denne gangen fikk jeg en feilmelding: «INSERT EXEC statement kan ikke nestes»

Kan jeg ikke bruke INSERT- og EXEC-setning samtidig?

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

Kommentarer

  • Du bør , dbfiddle.uk/… Vennligst legg til den lagrede prosedyren i spørsmålet, og merk SQL Server-versjonen din.

Svar

Hvis du ser på koden for spGetSites prosedyre, et eller annet sted i den prosedyren er en annen INSERT...EXEC. Det kan være direkte i den prosedyren, eller nestet i tarmene til en annen prosedyre det kaller.

Til slutt, hvis en lagret prosedyre bruker INSERT...EXEC, så hvis du prøver å ringe den lagrede prosedyren i sammenheng med en annen INSERT...EXEC, får du feilen du er ser .

Hvordan fikser du det?

  1. Du kan ganske enkelt ta det indre INSERT...EXEC og legge koden inn i dette enkelt lagret prosedyre. Selv om jeg mistenker at en annen prosedyre kan være der av en grunn: dvs. å holde koden din TØRR.

  2. Siden dette er en Get prosedyre, forhåpentligvis skjer det ingen datamanipulering noe sted i samtalestakken. Du kan konvertere barneprosedyren til en tabellverdig funksjon. Dette gjør at du kan konvertere den indre INSERT...EXEC til en INSERT...SELECT og løse dette problemet.

  3. Bruk temp-tabeller som er rettet mot den ytre prosedyren for å overføre data mellom prosedyrene. Denne løsningen blir komplisert, så det er ikke min favoritt, og jeg fraråder generelt dette mønsteret når det er et bedre alternativ – men for fullstendighetens skyld vil jeg inkludere det her. I utgangspunktet, hvis du oppretter #temp-tabellen din utenfor spGetSites, kan du bruke den inne i spGetSites (uten å lage den der inne), og tabellen med innlagte data vil overleve prosedyren og fortsette å jobbe.

Jeg liker ikke alternativ 3 fordi det er et kodemønster som er komplekst nok til å sikre at noen ødelegger det i fremtiden, med mindre alle er om bord og er kjent med kodingen mønster: * spGetSites mislykkes med mindre du oppretter tabellen først. Alle innringere må huske å lage bordet nøyaktig det samme først. * spGetSites kan ikke anta at tabellen er tom. Den kan ha eksisterende data fra den ytre samtalen (eller en tidligere utførelse fra samme innringer) * Feilsøking og feilsøking (og til og med få en spørringsplan) for spGetSites er mer kompleks på grunn av tabellopprettingsforvirringen.

Hva ville jeg gjort?

Uten å vite hvor kompleks koden er bak spGetSites, jeg ser på å lage en innebygd TVF som erstatter den indre INSERT...EXEC med INSERT...SELECT eller muligens alt spGetSites kan forenkles / skrives om for å gjøre det selvforsynt uten INSERT...EXEC

Legg igjen en kommentar

Din e-postadresse vil ikke bli publisert. Obligatoriske felt er merket med *