T-SQL Przechwytywanie wyniku z procedury wykonywanej w innej procedurze

Odpowiedz Nowy wątek
2016-03-07 11:03
0

Witam
Mam dwie procedury zewnętrzną i wewnętrzną. W zewnętrznej procedurze wykonywana jest wewnętrzna procedura oraz jakiś tam select. Druga procedura wywołuje jakiś tam select i zwraca mi wartość przy wykorzystaniu słowa kluczowego return. Sytuacja wygląda mniej więcej w ten sposób jak w przedstawionych poniżej przykładowych kodach źródłowych dwóch procedur.

Procedura zewnętrzna:


CREATE PROCEDURE OutsideProcedure @param1 int
AS
BEGIN
-- jakis kod

DECLARE @ResultInsideProcedure int
SELECT * FROM Table
EXECUTE @ResultInsideProcedure = [dbo].[InsideProcedure]
-- @ResultInsideProcedure zwróci wartość przypisaną do returna w procedurze wewnętrznej
END

Procedura wewnętrzna:


CREATE PROCEDURE InsideProcedure @param1 int
AS
BEGIN
SELECT * From AnotherTable
RETURN 1

END

Po wykonaniu procedur przy wykorzystaniu np. SQL Management Studio wszystko jest ok, wyświetla mi wyniki z procedury zewnętrznej i wewnętrznej. Schody zaczynają się dalej, ponieważ procedury mapowane są do serwisu WCF przy wykorzystaniu EF w wersji 4. Beznadziejne rozwiązanie bo mapowane są tylko procedury. Siłą rzeczy EF w wersji 4 mapuje mi wyniki z jednego selecta w procedurze zewnętrznej. Ja natomiast potrzebuje przechwycić wynik z procedury wewnętrznej.

Pytanie jak to zrobić tak by nie modyfikować procedury wewnętrznej ani nie stosować ADO.NET w serwisie.

Mam nadzieję, że jasno wytłumaczyłem problem.

edytowany 1x, ostatnio: a.dudek76, 2016-03-07 11:04

Pozostało 580 znaków

2016-03-07 11:18
0

Ale to nie możesz z EF po prostu wywołać tej wewnętrznej procedury?


"HUMAN BEINGS MAKE LIFE SO INTERESTING. DO YOU KNOW, THAT IN A UNIVERSE SO FULL OF WONDERS, THEY HAVE MANAGED TO INVENT BOREDOM."

Pozostało 580 znaków

2016-03-07 11:26
0
somekind napisał(a):

Ale to nie możesz z EF po prostu wywołać tej wewnętrznej procedury?

Teoretycznie tak, ale w tej zewnętrznej procedurze są wykonywane operacje (update) w ramach transakcji. Dopiero wykonanie wewnętrznej procedury w procedurze zewnętrznej po tych operacjach w ramach transakcji wyrzuca mi to co chce. Jeżeli wywołam samą procedurę wewnętrzną nie otrzymam żądanego efektu. Wiem rozwiązanie tutaj jest bardzo chaotyczne.

edytowany 1x, ostatnio: a.dudek76, 2016-03-07 11:26

Pozostało 580 znaków

2016-03-07 12:12
0

A jakby podejść w ten sposób:

CREATE PROCEDURE OutsideProcedure @param1 INT
AS
BEGIN
-- jakis kod

DECLARE @ResultInsideProcedure INT
EXECUTE @ResultInsideProcedure = [dbo].[InsideProcedure]
SELECT *,@ResultInsideProcedure as [ResultInsideProcedure] FROM TABLE

-- @ResultInsideProcedure zwróci wartość przypisaną do returna w procedurze wewnętrznej
END

Pozostało 580 znaków

2016-03-07 12:17
0
Panczo napisał(a):

A jakby podejść w ten sposób:


CREATE PROCEDURE OutsideProcedure @param1 INT
AS
BEGIN
-- jakis kod

DECLARE @ResultInsideProcedure INT
EXECUTE @ResultInsideProcedure = [dbo].[InsideProcedure]
SELECT *,@ResultInsideProcedure as [ResultInsideProcedure] FROM TABLE

-- @ResultInsideProcedure zwróci wartość przypisaną do returna w procedurze wewnętrznej
END



Nie wiem czy dobrze wytłumaczyłem. Twój kod zwróci mi rezultat z zewnętrznej procedury + return z wewnętrznej, ale ja chciałbym przechwycić całe zapytanie SELECT z wewnętrznej. Problem leży też tutaj, że ona ma na siłę przypisanego returna. Przy tym jest problem. Czyli chciałbym rezultat z zapytania w wewnętrznej procedurze przechwycić oprócz wartości zwracanej przy wykorzystaniu returna.

Pozostało 580 znaków

2016-03-07 12:27
0

Nie jestem specem od EF, ale poszedłbym w te storne: http://stackoverflow.com/ques[...]ecord-set-from-database-in-on

Pozostało 580 znaków

2016-03-07 12:49
1

EF 4 nie pozwala o ile mi wiadomo na zwrócenie więcej niż jeden z SELECT z procedury składowanej. Tutaj jest artykuł o tym gdzie napisano, że przed EF 5 takiej możliwości nie ma.
https://msdn.microsoft.com/en-us/data/jj691402.aspx

Pozostało 580 znaków

2016-03-07 13:45
1

Nie wiem co to EF, ale czy możesz skorzystać z tabeli tymczasowej tudzież zmiennej tabelarycznej w procedurze zewnętrznej i w wewnętrznej ładować dane do tabeli tym? Musiałbyś zapewne zmienić logikę procedury zewnętrznej, aby bazować na danych z tabeli czyli np zrobić select w zewnętrznej tak jak jest obecnie + select z tabeli tym po wykonaniu procedury wewnętrznej?

Czyli mniej więcej tak:

 CREATE PROCEDURE OutsideProcedure @param1 INT
AS
BEGIN
-- jakis kod

DECLARE @ResultInsideProcedure INT
SELECT * FROM TABLE
CREATE TABLE #Nazwa (-definicja tabeli-)
EXECUTE @ResultInsideProcedure = [dbo].[InsideProcedure]
-- @ResultInsideProcedure zwróci wartość przypisaną do returna w procedurze wewnętrznej
-- SELECT * FROM #Nazwa
END

CREATE PROCEDURE InsideProcedure @param1 INT
AS
BEGIN
INSERT INTO #Nazwa 
SELECT * FROM AnotherTable
-- Ewentualnie tu select jeśli musi być
RETURN 1

END

Wtedy procedura nadrzędnia zwróci wyniki z dwóch tabel (zew i wew). Ewentualnie procedura zew może mieć parametr aby działać tak jak obecnie + drugi parametr który zwróci tylko dane z wewnętrznej procedury.


Szkolenia, audyty, konsultacje SQL Server
Radkomp, sqlszkolenia
MCTS, MCiTP, MCSA, MCSE, MCT
http://sqlszkolenia.pl
edytowany 2x, ostatnio: firefox, 2016-03-07 13:49

Pozostało 580 znaków

2016-03-07 13:52

W zewnętrznej procedurze:


declare @temp_table table
(
    --kolumny tak jak w tej AnotherTable w wewn. procedurze
)

insert into @temp_table exec InsideProcedure @param1

I potem dodaj do rezultatu w zewn. procedurze. Czyli o to chyba koledze wyżej chodziło. Bo wpadł chyba na ten sam pomysł co ja.

edytowany 1x, ostatnio: mariano901229, 2016-03-07 13:52

Pozostało 580 znaków

2016-03-07 14:31
2
a.dudek76 napisał(a):

Teoretycznie tak, ale w tej zewnętrznej procedurze są wykonywane operacje (update) w ramach transakcji. Dopiero wykonanie wewnętrznej procedury w procedurze zewnętrznej po tych operacjach w ramach transakcji wyrzuca mi to co chce. Jeżeli wywołam samą procedurę wewnętrzną nie otrzymam żądanego efektu. Wiem rozwiązanie tutaj jest bardzo chaotyczne.

Entity Framework to abstrakcja nad bazą danych, jaki sens miałaby abstrakcja, która dopuszcza Cię do szczegółów implementacji? EF nic nie wie o tym, że wewnątrz jest jakaś procedura - on wie tylko o zewnętrznej procedurze, jej parametrach i zwracanym wyniku.
Jeśli chcesz się dobrać przez EF do wewnętrznej procedury, to musisz ją wywołać niezależnie. Jeśli przed jej wywołaniem potrzeba zrobić jakiś update, to musisz to zrobić z poziomu EF.
Alternatywnie, możesz napisać drugą wersję procedury zewnętrznej, która zrobi potrzebne update, wywoła wewnętrzną, a potem zwróci jej wynik.

Ot, uroki zaszywania logiki w bazie danych.


"HUMAN BEINGS MAKE LIFE SO INTERESTING. DO YOU KNOW, THAT IN A UNIVERSE SO FULL OF WONDERS, THEY HAVE MANAGED TO INVENT BOREDOM."

Pozostało 580 znaków

Odpowiedz
Liczba odpowiedzi na stronę

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0