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?

  1. 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Ý.

  2. 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 do INSERT...SELECT a vyřešte tento problém.

  3. 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

Napsat komentář

Vaše e-mailová adresa nebude zveřejněna. Vyžadované informace jsou označeny *