Van egy tárolt proc spGetSites, amely három oszlopot ad vissza a SiteName, a SiteId és az UnitCount számára. A tárolt proc tökéletesen fut. A tárolt proc eredményeit megpróbálom a @Site temp táblában tárolni, hogy a jelentésemhez használjam az alábbi szintaxist. Ezúttal hibaüzenetet kaptam: “Az INSERT EXEC utasítás nem ágyazható be”
Nem használhatom az INSERT és az EXEC utasításokat egyszerre?
DECLARE @Site TABLE (SiteName VARCHAR(100), SiteId INT, UnitCount INT) INSERT INTO @Site EXEC spGetSites @SiteId = 0
Megjegyzések
- Meg kell , dbfiddle.uk/… Kérjük, adjon hozzá tárolt eljárást a kérdéshez, és jelölje be az SQL Server verzióját.
Válasz
Ha megnézed a spGetSites
eljárás, valahol ebben az eljárásban van egy másik INSERT...EXEC
. Lehet, hogy közvetlenül benne van az eljárásban, vagy beágyazódik valamilyen más általa hívott eljárás belébe.
Végül, ha egy tárolt eljárás INSERT...EXEC
-et használ, akkor ha megpróbálja meghívni ezt a tárolt eljárást egy másik INSERT...EXEC
összefüggésben, akkor a hibát kapja látás .
Hogyan javítható?
-
Egyszerűen felveheti a belső
INSERT...EXEC
elemet, és ebbe illesztheti a kódot egyetlen tárolt eljárás. Bár gyanítom, hogy más eljárás is létezhet valamilyen okból: azaz hogy a kódot DRY-ban tartsa. -
Mivel ez egy
Get
eljárás, remélhetőleg a hívásveremben sehol nem történik adatkezelés. Átalakíthatná a gyermek eljárást táblázatértékű függvényre. Ez lehetővé tenné a belsőINSERT...EXEC
konvertálását. egyINSERT...SELECT
fájlba, és oldja meg ezt a problémát. -
A külső eljáráshoz hatótáblák segítségével továbbíthatja az adatokat az eljárások között. Ez a megoldás bonyolult, ezért nem a kedvencem, és általában elkedvetlenítem ezt a mintát, ha van jobb megoldás – de a teljesség kedvéért ide sorolom. Alapvetően, ha a #temp táblázatot a
spGetSites
kívül hozza létre, használhatja aspGetSites
oldalon (anélkül, hogy ott létrehozná), és a táblázatot a beillesztett adatokkal túléli az eljárás végrehajtását és tovább dolgozik.
A 3. opció nem tetszik, mert a kódolási minta elég bonyolult ahhoz, hogy valaki a jövőben elrontja, hacsak nem mindenki tartózkodik a fedélzeten és nem ismeri a kódolást minta: * spGetSites
sikertelen lesz, hacsak nem először hozza létre a táblázatot. Minden hívónak emlékeznie kell arra, hogy előbb pontosan ugyanezt hozza létre. * spGetSites
nem feltételezheti, hogy a tábla üres. Lehet, hogy a külső hívásból származó adatok (vagy ugyanazon hívó előzetes végrehajtása) vannak. * Hibaelhárítás és hibakeresés (és még egy lekérdezési terv) a (z) spGetSites
fájlhoz összetettebb, mert a táblázat létrehozása zavaros.
Mit tennék?
Anélkül, hogy tudnánk, mennyire összetett a kód a spGetSites
mögött van, egy belső TVF-et szeretnék létrehozni, amely a belső INSERT...EXEC
helyét INSERT...SELECT
vagy esetleg az összes spGetSites
egyszerűsíthető / átírható, hogy önállóvá váljon a INSERT...EXEC