Mám uložený proc spGetSites, který vrací tři sloupce pro SiteName, SiteId a UnitCount. Uložený program běží naprosto v pořádku. Pokouším se uložit výsledky uloženého proc do dočasné tabulky @Site, která se použije pro můj přehled, s níže uvedenou syntaxí. Tentokrát se mi zobrazila chybová zpráva: „INSERT EXEC statement cannot be nested“
Nemohu používat příkazy INSERT a EXEC současně?
DECLARE @Site TABLE (SiteName VARCHAR(100), SiteId INT, UnitCount INT) INSERT INTO @Site EXEC spGetSites @SiteId = 0
Komentáře
- Měli byste , dbfiddle.uk/… Přidejte k otázce uloženou proceduru a označte svou verzi serveru SQL.
Odpověď
Pokud se podíváte na kód vaší spGetSites
procedura, někde v této proceduře je další INSERT...EXEC
. Může být přímo v této proceduře nebo vnořená do útrob nějaké jiné procedury, kterou volá.
Nakonec pokud uložená procedura používá INSERT...EXEC
, pak pokud se pokusíte tuto uloženou proceduru zavolat v kontextu jiné INSERT...EXEC
, zobrazí se chyba, že jste vidění .
Jak to napravíte?
-
Můžete jednoduše použít vnitřní
INSERT...EXEC
a vložit do něj kód jediná uložená procedura. Mám však podezření, že může existovat jiný postup z nějakého důvodu: tj. Aby byl váš kód SUCHÝ. -
Protože se jedná o
Get
postup, doufejme, že kdekoli v zásobníku volání nedojde k žádné manipulaci s daty. Podřízenou proceduru můžete převést na funkci s hodnotou tabulky. To by vám umožnilo převést tento vnitřníINSERT...EXEC
doINSERT...SELECT
a vyřešte tento problém. -
K předávání dat mezi procedurami použijte dočasné tabulky s rozsahem k vnější proceduře. komplikované, takže to není můj oblíbený, a obecně od tohoto vzorce odradím, když existuje lepší volba – ale pro úplnost jej sem zahrnu. V zásadě platí, že pokud vytvoříte tabulku #temp mimo
spGetSites
, můžete ji použít uvnitřspGetSites
(aniž byste ji tam vytvořili) a tabulku s vloženými daty přežije provedení procedury a bude pokračovat v práci.
Nelíbí se mi možnost 3, protože je to kódovací vzor natolik složitý, aby zajistil, že to někdo v budoucnu pokazí, pokud nebudou všichni na palubě a neznají kódování pattern: * spGetSites
selže, pokud nejprve nevytvoříte tabulku. Všichni volající si musí pamatovat, aby nejprve vytvořili tabulku přesně stejnou. * spGetSites
nelze předpokládat, že je tabulka prázdná. Může mít existující data z vnějšího volání (nebo předchozí spuštění od stejného volajícího) * Odstraňování problémů a ladění (a dokonce i získání plán dotazů) pro spGetSites
je složitější kvůli nejasnostem při vytváření tabulky.
Co bych udělal?
Aniž bych věděl, jak složitý je kód je za spGetSites
, podívám se do vytvoření vloženého TVF, který nahradí vnitřní INSERT...EXEC
INSERT...SELECT
nebo případně všechny spGetSites
lze zjednodušit / přepsat tak, aby bylo samostatné bez INSERT...EXEC