Mam trzy procedury przechowywane Sp1
, Sp2
i Sp3
.
Pierwsza ( Sp1
) wykona drugą ( Sp2
) i zapisze zwrócone dane do, @tempTB1
a druga wykona trzecią ( Sp3
) i zapisze dane do @tempTB2
.
Jeśli wykonam Sp2
to zadziała i zwróci mi wszystkie moje dane z Sp3
, ale problem tkwi w Sp1
, gdy wykonam to wyświetli ten błąd:
Instrukcja INSERT EXEC nie może być zagnieżdżona
Próbowałem zmienić miejsce execute Sp2
i wyświetla mi się kolejny błąd:
Nie można użyć instrukcji ROLLBACK w instrukcji INSERT-EXEC.
sp_help_jobactivity
).To jedyny „prosty” sposób na zrobienie tego w SQL Server bez jakiejś gigantycznej, zawiłej utworzonej funkcji lub wykonanego wywołania ciągu sql, z których oba są okropnymi rozwiązaniami:
PRZYKŁAD:
Uwaga : MUSISZ użyć opcji „set fmtonly off”, ORAZ NIE MOŻESZ dodać do tego dynamicznego sql ani w wywołaniu openrowset, ani dla ciągu zawierającego parametry procedury składowanej, ani dla nazwy tabeli. Dlatego musisz używać tabeli tymczasowej zamiast zmiennych tabeli, co byłoby lepsze, ponieważ w większości przypadków wykonuje ona tabelę tymczasową.
źródło
OK, zachęcony przez jimharka, oto przykład starego podejścia z pojedynczą tabelą mieszania: -
źródło
Moje obejście tego problemu zawsze polegało na stosowaniu zasady, że pojedyncze tabele tymczasowe z mieszaniem są objęte zakresem wszystkich nazwanych procesów. Więc mam przełącznik opcji w parametrach proc (domyślnie wyłączony). Jeśli ta opcja jest włączona, wywołany proc wstawi wyniki do tabeli tymczasowej utworzonej w procesie wywołującym. Myślę, że w przeszłości poszedłem o krok dalej i umieściłem kod w wywołanym procencie, aby sprawdzić, czy pojedyncza tabela skrótów istnieje w zakresie, jeśli tak, to wstaw kod, w przeciwnym razie zwróć zestaw wyników. Wydaje się, że działa dobrze - najlepszy sposób na przekazywanie dużych zestawów danych między procesami.
źródło
Ta sztuczka mi pasuje.
Nie masz tego problemu na serwerze zdalnym, ponieważ na serwerze zdalnym ostatnie polecenie wstawiania czeka na wykonanie poprzedniego polecenia. Nie dotyczy to tego samego serwera.
Skorzystaj z tej sytuacji, aby obejść ten problem.
Jeśli masz uprawnienia do tworzenia serwera połączonego, zrób to. Utwórz ten sam serwer, co serwer połączony.
teraz twoje polecenie Sql w dodatku SP1 to
Uwierz mi, to działa nawet jeśli masz dynamiczną wstawkę w SP2
źródło
Znalazłem rozwiązanie polegające na przekształceniu jednego z produktów w funkcję wartościowaną w tabeli. Zdaję sobie sprawę, że nie zawsze jest to możliwe i wprowadza własne ograniczenia. Jednak zawsze przynajmniej jedna z procedur była do tego dobrym kandydatem. Podoba mi się to rozwiązanie, ponieważ nie wprowadza żadnych „hacków” do rozwiązania.
źródło
Napotkałem ten problem podczas próby zaimportowania wyników Stored Proc do tabeli tymczasowej, a ten Stored Proc został wstawiony do tabeli tymczasowej jako część własnej operacji. Problem polega na tym, że SQL Server nie pozwala temu samemu procesowi na zapis do dwóch różnych tabel tymczasowych w tym samym czasie.
Zaakceptowana odpowiedź OPENROWSET działa dobrze, ale musiałem uniknąć używania w moim procesie dowolnego Dynamic SQL lub zewnętrznego dostawcy OLE, więc poszedłem inną drogą.
Jednym z łatwych obejść, które znalazłem, była zmiana tabeli tymczasowej w mojej procedurze składowanej na zmienną tabeli. Działa dokładnie tak samo, jak w przypadku tabeli tymczasowej, ale nie powoduje już konfliktu z inną wstawką do tabeli tymczasowej.
Żeby zapomnieć o komentarzu, wiem, że kilku z was ma zamiar napisać, ostrzegając mnie przed zmiennymi tabeli jako zabójcami wydajności ... Mogę wam tylko powiedzieć, że w 2020 roku opłaca się nie bać się zmiennych tabeli. Gdyby to był rok 2008, a moja baza danych była hostowana na serwerze z 16 GB pamięci RAM i dyskami twardymi 5400 obr./min, mógłbym się z tobą zgodzić. Ale jest rok 2020 i mam macierz SSD jako moją podstawową pamięć masową i setki gigabajtów pamięci RAM. Mógłbym załadować całą bazę danych mojej firmy do zmiennej tabeli i nadal mieć dużo wolnego miejsca w pamięci RAM.
Zmienne tabeli wróciły do menu!
źródło
Miałem ten sam problem i niepokój związany z powieleniem kodu w dwóch lub więcej sprocesach. Skończyło się na dodaniu dodatkowego atrybutu dla „trybu”. Pozwoliło to na istnienie wspólnego kodu wewnątrz jednego sproc oraz przepływu skierowanego w trybie i zbioru wyników sproc.
źródło
co powiesz na zapisanie wyniku w tabeli statycznej? Lubić
nie jest to idealne rozwiązanie, ale jest tak proste i nie trzeba wszystkiego przepisywać.
AKTUALIZACJA : poprzednie rozwiązanie nie działa dobrze z równoległymi zapytaniami (asynchroniczne i dostęp dla wielu użytkowników), dlatego teraz używam tabel tymczasowych
spGetData
zawartość zagnieżdżonej procedury składowanejźródło
Zadeklaruj wyjściową zmienną kursora do wewnętrznego sp:
Następnie zadeklaruj kursor c do zaznaczenia, które chcesz zwrócić. Następnie otwórz kursor. Następnie ustaw odniesienie:
NIE zamykaj ani nie przydzielaj ponownie.
Teraz wywołaj wewnętrzne sp z zewnętrznego, podając parametr kursora, taki jak:
Po wykonaniu wewnętrznego sp, twój
@cOUT
jest gotowy do pobrania. Zapętl, a następnie zamknij i zwolnij przydział.źródło
Jeśli potrafisz korzystać z innych powiązanych technologii, takich jak C #, sugeruję użycie wbudowanego polecenia SQL z parametrem Transaction.
Stworzyłem prostą aplikację konsolową, która demonstruje tę umiejętność, którą można znaleźć tutaj: https://github.com/hecked12/SQL-Transaction-Using-C-Sharp
Krótko mówiąc, C # pozwala przezwyciężyć to ograniczenie, w którym można sprawdzić dane wyjściowe każdej procedury składowanej i użyć ich w dowolny sposób, na przykład można je przekazać do innej procedury składowanej. Jeśli wynik jest w porządku, możesz zatwierdzić transakcję, w przeciwnym razie możesz cofnąć zmiany za pomocą wycofywania.
źródło
W SQL Server 2008 R2 wystąpiła niezgodność w kolumnach tabeli, która spowodowała błąd wycofywania zmian. To zniknęło, kiedy naprawiłem moją zmienną tabeli sqlcmd wypełnioną instrukcją insert-exec, aby pasowała do tej zwróconej przez przechowywany proc. Brakowało kodu_organizacji. W pliku cmd systemu Windows ładuje wynik procedury składowanej i wybiera go.
źródło