Jeg har en gemt proc spGetSites, der returnerer tre kolonner til SiteName, SiteId og UnitCount. Den lagrede proc kører helt fint. Jeg prøver at gemme resultaterne af den lagrede proc til en temp-tabel @Site til brug for min rapport med nedenstående syntaks. Denne gang fik jeg en fejlmeddelelse: “INSERT EXEC-sætning kan ikke indlejres”

Kan jeg ikke bruge INSERT- og EXEC-erklæringen på samme tid?

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

Kommentarer

  • Du skal , dbfiddle.uk/… Tilføj din gemte procedure til spørgsmålet, og tag din SQL Server-version.

Svar

Hvis du ser på koden til din spGetSites procedure, et eller andet sted i denne procedure er en anden INSERT...EXEC. Det kan være direkte i denne procedure eller indlejret i tarmene ved en anden procedure, det kalder.

I sidste ende Hvis en gemt procedure bruger INSERT...EXEC så får du den fejl, du er, hvis du prøver at kalde den lagrede procedure i sammenhæng med en anden INSERT...EXEC ser .

Hvordan løser du det?

  1. Du kan simpelthen tage det indre INSERT...EXEC og integrere koden til dette enkelt lagret procedure. Jeg formoder dog, at en anden procedure kan være der af en grund: dvs. at holde din kode TØR.

  2. Da dette er en Get procedure, forhåbentlig sker der ingen datamanipulation overalt i opkaldstakken. Du kan konvertere barnproceduren til en tabelværdifunktion. Dette giver dig mulighed for at konvertere den indre INSERT...EXEC i en INSERT...SELECT og løse dette problem.

  3. Brug temp-tabeller, der er omfattet af den ydre procedure for at videregive data mellem procedurer. Denne løsning får kompliceret, så det er ikke min favorit, og jeg fraråder mig generelt dette mønster, når der er en bedre mulighed – men for fuldstændighedens skyld vil jeg inkludere det her. Dybest set, hvis du opretter din #temp-tabel uden for spGetSites, kan du bruge den inde i spGetSites (uden at oprette den derinde), og tabellen med indsatte data vil overleve procedurens udførelse og fortsætte med at arbejde.

Jeg kan ikke lide valgmulighed 3, fordi det er et kodemønster, der er så komplekst, at det sikres, at nogen ødelægger det i fremtiden, medmindre alle er om bord og kender kodningen mønster: * spGetSites mislykkes, medmindre du opretter tabellen først. Alle opkaldere skal huske at oprette tabellen nøjagtigt den samme først. * spGetSites kan ikke antage, at tabellen er tom. Den kan have eksisterende data fra det ydre opkald (eller en tidligere udførelse fra den samme opkalder) * Fejlfinding og fejlretning (og endda få en forespørgselsplan) for spGetSites er mere kompleks på grund af forvirring af tabeloprettelsen.

Hvad ville jeg gøre?

Uden at vide, hvor kompleks den koden er bag spGetSites, jeg ser på at oprette en indbygget TVF, der erstatter den indre INSERT...EXEC med INSERT...SELECT eller muligvis hele spGetSites kunne forenkles / omskrives for at gøre det selvstændigt uden INSERT...EXEC

Skriv et svar

Din e-mailadresse vil ikke blive publiceret. Krævede felter er markeret med *