Jak mam to zrobić SELECT * INTO [temp table] FROM [stored procedure]
? Nie FROM [Table]
i bez definicji [temp table]
?
Select
wszystkie dane z BusinessLine
do tmpBusLine
działa dobrze.
select *
into tmpBusLine
from BusinessLine
Próbuję tego samego, ale użycie stored procedure
zwracającego dane nie jest takie samo.
select *
into tmpBusLine
from
exec getBusinessLineHistory '16 Mar 2009'
Komunikat wyjściowy:
Msg 156, poziom 15, stan 1, wiersz 2 Niepoprawna składnia w pobliżu słowa kluczowego „exec”.
Przeczytałem kilka przykładów tworzenia tabeli tymczasowej o tej samej strukturze co wyjściowa procedura składowana, która działa dobrze, ale fajnie byłoby nie podawać żadnych kolumn.
Odpowiedzi:
Możesz do tego użyć OPENROWSET . Spójrz. Dołączyłem również kod sp_configure, aby włączyć rozproszone zapytania Ad Hoc, na wypadek, gdyby nie zostało jeszcze włączone.
źródło
Jeśli chcesz to zrobić bez uprzedniego zadeklarowania tabeli tymczasowej, możesz spróbować utworzyć funkcję zdefiniowaną przez użytkownika zamiast procedury składowanej i sprawić, by funkcja zdefiniowana przez użytkownika zwróciła tabelę. Alternatywnie, jeśli chcesz skorzystać z procedury składowanej, spróbuj czegoś takiego:
źródło
W SQL Server 2005 można użyć
INSERT INTO ... EXEC
do wstawienia wyniku procedury składowanej do tabeli. Z dokumentacji MSDNINSERT
(w rzeczywistości dla SQL Server 2000):źródło
To jest odpowiedź na nieco zmodyfikowaną wersję twojego pytania. Jeśli możesz zrezygnować z procedury składowanej dla funkcji zdefiniowanej przez użytkownika, możesz użyć wbudowanej funkcji zdefiniowanej przez użytkownika o wartościach przechowywanych w tabeli. Zasadniczo jest to procedura składowana (pobiera parametry), która zwraca tabelę jako zestaw wyników; i dlatego będzie ładnie umieścić z oświadczeniem INTO.
Oto dobry szybki artykuł na ten temat i innych funkcji zdefiniowanych przez użytkownika. Jeśli nadal potrzebujesz sterowanej procedury składowanej, możesz owinąć wbudowaną funkcję tabelową zdefiniowaną przez użytkownika funkcją procedury składowanej. Procedura przechowywana po prostu przekazuje parametry, gdy wywołuje select * z wbudowanej funkcji zdefiniowanej przez użytkownika o wartościach przechowywanych w tabeli.
Na przykład masz wbudowaną funkcję zdefiniowaną przez użytkownika o wartości tabeli, aby uzyskać listę klientów dla określonego regionu:
Następnie możesz wywołać tę funkcję, aby uzyskać takie wyniki, jak:
Lub zrobić WYBIERZ W:
Jeśli nadal potrzebujesz procedury składowanej, zawiń funkcję jako taką:
Myślę, że jest to najbardziej „bezhackowa” metoda uzyskiwania pożądanych rezultatów. Wykorzystuje istniejące funkcje, ponieważ były przeznaczone do użycia bez dodatkowych komplikacji. Poprzez zagnieżdżenie wbudowanej funkcji zdefiniowanej przez użytkownika w tabeli w procedurze przechowywanej, masz dostęp do tej funkcji na dwa sposoby. Plus! Masz tylko jeden punkt obsługi rzeczywistego kodu SQL.
Sugerowano użycie OPENROWSET, ale nie do tego służy funkcja OPENROWSET (From Books Online):
Użycie OPENROWSET wykona zadanie, ale spowoduje dodatkowe obciążenie związane z otwieraniem połączeń lokalnych i przesyłaniem danych. Może również nie być opcją we wszystkich przypadkach, ponieważ wymaga zezwolenia na zapytania ad hoc, które stanowi zagrożenie dla bezpieczeństwa i dlatego może nie być pożądane. Ponadto podejście OPENROWSET wyklucza stosowanie procedur przechowywanych zwracających więcej niż jeden zestaw wyników. Można to osiągnąć dzięki zawinięciu wielu funkcji zdefiniowanych przez użytkownika w wartość tabeli w jednej procedurze składowanej.
źródło
źródło
Jeśli nie znasz schematu, możesz wykonać następujące czynności. Należy pamiętać, że ta metoda wiąże się z poważnym zagrożeniem bezpieczeństwa.
źródło
Gdy procedura przechowywana zwraca wiele kolumn, a Ty nie chcesz ręcznie „tworzyć” tabeli tymczasowej do przechowywania wyniku, znalazłem najłatwiejszy sposób, aby przejść do procedury przechowywanej i dodać klauzulę „do” na ostatnia instrukcja select i dodaj 1 = 0 do klauzuli where.
Uruchom procedurę składowaną raz i wróć i usuń właśnie dodany kod SQL. Teraz będziesz mieć pustą tabelę pasującą do wyniku procedury składowanej. Możesz albo „utworzyć skrypt tabeli jako tworzenie” dla tabeli tymczasowej, albo po prostu wstawić bezpośrednio do tej tabeli.
źródło
SELECT INTO
tabelę tymczasową i tworzysz tabelę skryptów podczas tworzenia z tabeli tymczasowej? Pojawiają się tabele tymczasowe,tempdb
ale nie mogę kliknąć prawym przyciskiem myszy i utworzyć skryptu. Każda pomoc jest mile widziana.select ... into new_table
domyślnie utworzyć rzeczywistą tabelę.declare @s varchar(max)='';select @s=@s+','+COLUMN_NAME+' '+DATA_TYPE+isnull('('+case CHARACTER_MAXIMUM_LENGTH when -1 then 'max' else cast(CHARACTER_MAXIMUM_LENGTH as varchar(10))end+')','')from INFORMATION_SCHEMA.COLUMNS where TABLE_NAME='...';select @s
źródło
Czy procedura przechowywana pobiera tylko dane lub je modyfikuje? Jeśli jest używany tylko do pobierania, możesz przekonwertować procedurę przechowywaną na funkcję i użyć wspólnych wyrażeń tabelowych (CTE) bez konieczności deklarowania jej w następujący sposób:
Jednak wszystko, co należy pobrać z CTE, powinno być użyte tylko w jednej instrukcji. Nie możesz zrobić a
with temp as ...
i spróbować użyć go po kilku wierszach SQL. Możesz mieć wiele CTE w jednej instrukcji dla bardziej złożonych zapytań.Na przykład,
źródło
Jeśli tabela wyników przechowywanego procesu jest zbyt skomplikowana, aby ręcznie wpisać instrukcję „utwórz tabelę” i nie możesz użyć OPENQUERY OR OPENROWSET, możesz użyć sp_help do wygenerowania listy kolumn i typów danych. Gdy masz już listę kolumn, wystarczy sformatować ją zgodnie z własnymi potrzebami.
Krok 1: Dodaj „do #temp” do zapytania wyjściowego (np. „Wybierz [...] do #temp z [...]”).
Najprostszym sposobem jest bezpośrednia edycja zapytania wyjściowego w proc. jeśli nie możesz zmienić zapisanego proc, możesz skopiować zawartość do nowego okna zapytania i tam zmodyfikować zapytanie.
Krok 2: Uruchom sp_help w tabeli tymczasowej. (np. „exec tempdb..sp_help #temp”)
Po utworzeniu tabeli tymczasowej uruchom sp_help w tabeli tymczasowej, aby uzyskać listę kolumn i typów danych, w tym wielkość pól varchar.
Krok 3: Skopiuj kolumny danych i typy do instrukcji tworzenia tabeli
Mam arkusz programu Excel, którego używam do sformatowania danych wyjściowych sp_help w instrukcji „create table”. Nie potrzebujesz nic szczególnego, wystarczy skopiować i wkleić do edytora SQL. Użyj nazw, rozmiarów i typów kolumn, aby skonstruować instrukcję „Utwórz tabelę x [...]” lub „deklaruj @ x tabelę [...]”, której można użyć do wstawienia wyników procedury składowanej.
Krok 4: Wstaw do nowo utworzonej tabeli
Teraz będziesz mieć zapytanie podobne do innych rozwiązań opisanych w tym wątku.
Tej techniki można również użyć do konwersji tabeli tymczasowej (
#temp
) na zmienną tabelową (@temp
). Chociaż może to być więcej niż tylkocreate table
samodzielne napisanie instrukcji, zapobiega ręcznym błędom, takim jak literówki i niedopasowania typów danych w dużych procesach. Debugowanie literówki może zająć więcej czasu niż napisanie zapytania.źródło
Jeśli OPENROWSET powoduje problemy, istnieje inny sposób od 2012 roku; skorzystać z sys.dm_exec_describe_first_result_set_for_object, jak wspomniano tutaj: odzyskać nazwy kolumn i typy procedury przechowywanej?
Najpierw utwórz tę procedurę składowaną, aby wygenerować SQL dla tabeli tymczasowej:
Aby skorzystać z tej procedury, wywołaj ją w następujący sposób:
Zauważ, że używam globalnej tabeli tymczasowej. Jest tak, ponieważ użycie EXEC do uruchomienia dynamicznego SQL tworzy własną sesję, więc zwykła tabela tymczasowa byłaby poza zakresem dla jakiegokolwiek kolejnego kodu. Jeśli globalne tabeli tymczasowej jest problem, to można użyć zwykłej tabeli tymczasowej, ale każda następna SQL musiałyby być dynamiczny, to znaczy wykonywane również przez instrukcję EXEC.
źródło
@SQL
.Quassnoi umieścił mnie tam przez większość czasu, ale brakowało jednej rzeczy:
**** Musiałem użyć parametrów w procedurze przechowywanej. ****
I OPENQUERY nie pozwala na to:
Znalazłem więc sposób na pracę z systemem, a także nie musiałem usztywniać definicji tabeli i redefiniować ją w innej procedurze przechowywanej (i oczywiście ryzykować, że się zepsuje)!
Tak, można dynamicznie utworzyć definicję tabeli zwróconą z procedury składowanej za pomocą instrukcji OPENQUERY z fałszywymi zmiennymi (o ile zestaw NO RESULT zwraca taką samą liczbę pól i znajduje się w tej samej pozycji co zestaw danych z dobrymi danymi).
Po utworzeniu tabeli możesz używać procedury przechowywanej exec do tabeli tymczasowej przez cały dzień.
Aby pamiętać (jak wskazano powyżej), musisz włączyć dostęp do danych,
Kod:
Dzięki za informacje, które zostały dostarczone pierwotnie ... Tak, w końcu nie muszę tworzyć tych wszystkich fałszywych (ścisłych) definicji tabeli podczas korzystania z danych z innej procedury składowanej lub bazy danych i tak, możesz również użyć parametrów.
Wyszukaj tagi referencyjne:
Procedura przechowywana SQL 2005 do tabeli temp
openquery z procedurą składowaną i zmiennymi 2005
openquery ze zmiennymi
wykonać procedurę przechowywaną w tabeli temp
Aktualizacja: nie będzie działać z tabelami tymczasowymi więc musiałem skorzystać z ręcznego tworzenia tabeli tymczasowej.
Uwaga Bummer : nie będzie działać z tymczasowymi stolikami , http://www.sommarskog.se/share_data.html#OPENQUERY
Odniesienie: Następną rzeczą jest zdefiniowanie LOCALSERVER. W tym przykładzie może wyglądać jak słowo kluczowe, ale w rzeczywistości jest to tylko nazwa. Tak to się robi:
Aby utworzyć serwer połączony, musisz mieć uprawnienie ZMIENIĆ DOWOLNY SERWER lub być członkiem dowolnej ze stałych ról serwera sysadmin lub setupadmin.
OPENQUERY otwiera nowe połączenie z SQL Server. Ma to pewne implikacje:
Procedura wywoływana za pomocą OPENQUERY nie może odwoływać się do tabel tymczasowych utworzonych w bieżącym połączeniu.
Nowe połączenie ma własną domyślną bazę danych (zdefiniowaną przez sp_addlinkedserver, domyślnie jest to master), więc cała specyfikacja obiektu musi zawierać nazwę bazy danych.
Jeśli masz otwartą transakcję i trzymasz blokady podczas wywoływania OPENQUERY, wywoływana procedura nie może uzyskać dostępu do tego, co blokujesz. Oznacza to, że jeśli nie będziesz ostrożny, sam się zablokujesz.
Łączenie nie jest bezpłatne, więc występuje obniżenie wydajności.
źródło
SELECT @@SERVERNAME
. Możesz także użyćEXEC sp_serveroption @@SERVERNAME, 'DATA ACCESS', TRUE
Jeśli masz szczęście, że masz SQL 2012 lub nowszy, możesz użyć
dm_exec_describe_first_result_set_for_object
Właśnie edytowałem sql dostarczone przez gotqn. Dzięki, gotqn.
Spowoduje to utworzenie globalnej tabeli temp o nazwie takiej samej jak nazwa procedury. Tabela temperatur może być później używana zgodnie z wymaganiami. Tylko nie zapomnij upuścić go przed ponownym uruchomieniem.
źródło
sys.all_objects
zamiast,sys.procedures
jeśli chcesz to zrobić dla wbudowanych procedur przechowywanych.Ten zapisany proces wykonuje zadanie:
Jest to drobna przeróbka tego: wstaw wyniki procedury przechowywanej do tabeli , aby faktycznie działała.
Jeśli chcesz, aby działał ze stołem tymczasowym, musisz użyć
##GLOBAL
stołu i upuścić go później.źródło
Aby wstawić pierwszy zestaw rekordów procedury składowanej do tabeli tymczasowej, musisz wiedzieć:
sp_executesql
)Powyższe może wyglądać na ograniczenie, ale IMHO ma sens - jeśli używasz
sp_executesql
, możesz raz zwrócić dwie kolumny i raz dziesięć, a jeśli masz wiele zestawów wyników, nie możesz również wstawić ich do kilku tabel - możesz wstawić maksimum w dwóch tabelach w jednej instrukcji T-SQL (przy użyciuOUTPUT
klauzuli i bez wyzwalaczy).Problem polega głównie na zdefiniowaniu tymczasowej struktury tabeli przed wykonaniem
EXEC ... INTO ...
instrukcji.Pierwszy działa z,
OBJECT_ID
podczas gdy drugi i trzeci działa również z zapytaniami Ad-hoc. Wolę używać DMV zamiast sp, ponieważ możesz używaćCROSS APPLY
i budować tymczasowe definicje tabel dla wielu procedur jednocześnie.Zwróć także uwagę na
system_type_name
pole, ponieważ może być bardzo przydatne. Przechowuje pełną definicję kolumny. Na przykład:i możesz użyć go bezpośrednio w większości przypadków, aby utworzyć definicję tabeli.
Tak więc myślę, że w większości przypadków (jeśli procedura przechowywana spełnia określone kryteria) możesz łatwo zbudować dynamiczne instrukcje rozwiązywania takich problemów (utwórz tabelę tymczasową, wstaw wynik w niej przechowywany, rób to, czego potrzebujesz z danymi) .
Należy zauważyć, że powyższe obiekty nie definiują danych pierwszego zestawu wyników w niektórych przypadkach, takich jak wykonanie dynamicznych instrukcji T-SQL lub użycie tymczasowych tabel w procedurze przechowywanej.
źródło
Teraz wiem, jaki jest wynik mojej procedury, dlatego wykonuję następujące zapytanie.
WARTOŚCI (10, 5, 1, NULL) SET IDENTITY_INSERT [dbo]. [TblTestingTree] Wł.
źródło
Jeśli zapytanie nie zawiera parametru, użyj
OpenQuery
innego użyciaOpenRowset
.Podstawową rzeczą byłoby utworzenie schematu zgodnie z procedurą przechowywaną i wstawienie do tej tabeli. na przykład:
źródło
Kod
Mam nadzieję, że to pomoże. Zakwalifikuj się odpowiednio.
źródło
Znalazłem przekazywanie tablic / tabel danych do przechowywanych procedur, które mogą dać ci inny pomysł na rozwiązanie problemu.
Łącze sugeruje użycie parametru typu obrazu do przejścia do procedury składowanej. Następnie w procedurze przechowywanej obraz jest przekształcany w zmienną tabelową zawierającą oryginalne dane.
Być może istnieje sposób, w jaki można tego użyć z tymczasowym stołem.
źródło
Spotkałem ten sam problem i oto, co z tym zrobiłem sugestii Paula . Najważniejsze jest tutaj,
NEWID()
aby uniknąć jednoczesnego uruchamiania procedur / skryptów przez wielu użytkowników, co jest problemem dla globalnej tabeli tymczasowej.źródło
Inną metodą jest utworzenie typu i użycie PIPELINED, aby następnie przekazać obiekt. Ogranicza się to jednak do znajomości kolumn. Ma jednak tę zaletę, że potrafi:
źródło
Jest to prosty 2-etapowy proces: - utwórz tymczasowy stół - Wstaw do tymczasowego stołu.
Kod do wykonania tego samego:
źródło
Po przeszukaniu znalazłem sposób, aby dynamicznie utworzyć tabelę temp dla dowolnej procedury składowanej bez użycia
OPENROWSET
lubOPENQUERY
używania ogólnego schematu definicji wyniku procedury składowanej, zwłaszcza gdy nie jesteś administratorem bazy danych.Serwer Sql ma wbudowany proc,
sp_describe_first_result_set
który może dostarczyć schemat dowolnego zestawu wyników procedur. Utworzyłem tabelę schematów na podstawie wyników tej procedury i ręcznie ustawiłem wszystkie pola na NULLABLE.Możesz dostosować schemat używanej wersji serwera SQL (jeśli to konieczne).
źródło
Jeśli znasz parametry, które są przekazywane, i jeśli nie masz dostępu do sp_configure, edytuj procedurę przechowywaną z tymi parametrami i to samo można zapisać w tabeli globalnej ##.
źródło
Można to zrobić w programie SQL Server 2014+, pod warunkiem że procedura składowana zwraca tylko jedną tabelę. Jeśli ktoś znajdzie sposób na zrobienie tego dla wielu tabel, chciałbym o tym wiedzieć.
Spowoduje to pobranie definicji zwróconej tabeli z tabel systemowych i wykorzystanie jej do utworzenia tabeli tymczasowej. Następnie można wypełnić go z procedury przechowywanej, jak podano wcześniej.
Istnieją również warianty tego, które działają również z dynamicznym SQL.
źródło
Kilka lat spóźniłem się na to pytanie, ale potrzebowałem czegoś takiego do szybkiego i brudnego generowania kodu. Sądzę, że jak inni stwierdzili, po prostu łatwiej jest zdefiniować tabelę tymczasową z góry, ale ta metoda powinna działać w przypadku prostych zapytań procedur przechowywanych lub instrukcji SQL.
To będzie trochę skomplikowane, ale pożycza od współtwórców tutaj, jak również rozwiązanie Paula White'a z DBA Stack Exchange Uzyskaj kolumny wyników typu procedura przechowywana . Ponownie, aby powtórzyć to podejście i przykład nie jest przeznaczony dla procesów w środowisku wielu użytkowników. W tym przypadku definicja tabeli jest ustawiana na krótki czas w globalnej tabeli tymczasowej w celu odniesienia przez proces szablonu generowania kodu.
Nie przetestowałem tego w pełni, więc mogą istnieć zastrzeżenia, więc możesz przejść do linku MSDN w odpowiedzi Paula White'a. Dotyczy to SQL 2012 i nowszych wersji.
Najpierw użyj procedury składowanej sp_describe_first_result_set, która przypomina opis Oracle.
Spowoduje to ocenę pierwszego wiersza pierwszego zestawu wyników, więc jeśli procedura składowana lub instrukcja zwróci wiele zapytań, będzie opisywać tylko pierwszy wynik.
Utworzyłem przechowywany proc, aby rozbić zadania, które zwracają pojedyncze pole do wyboru, aby utworzyć definicję tabeli temp.
Zagadką jest to, że musisz użyć tabeli globalnej, ale musisz uczynić ją wystarczająco wyjątkową, abyś mógł z niej często tworzyć i tworzyć bez obaw o kolizję.
W przykładzie użyłem Guid (FE264BF5_9C32_438F_8462_8A5DC8DEE49E) dla zmiennej globalnej, zastępując łączniki znakiem podkreślenia
Ponownie przetestowałem go tylko z prostymi zapytaniami z procedury składowanej i prostymi zapytaniami, więc twój przebieg może się różnić. Mam nadzieję, że to komuś pomoże.
źródło
Cóż, musisz utworzyć tabelę tymczasową, ale nie musi ona mieć odpowiedniego schematu ... Utworzyłem procedurę składowaną, która modyfikuje istniejącą tabelę tymczasową, tak aby zawierała wymagane kolumny z odpowiednimi danymi wpisz i uporządkuj (usuwając wszystkie istniejące kolumny, dodając nowe kolumny):
Uwaga: to nie zadziała, jeśli sys.dm_exec_describe_first_result_set_set_object nie może określić wyników procedury składowanej (na przykład, jeśli używa tabeli tymczasowej).
źródło
Jeśli zezwolisz dynamicznemu SQL na utworzenie tabeli tymczasowej, ta tabela jest własnością połączenia dynamicznego SQL, w przeciwieństwie do połączenia, z którego wywoływana jest procedura składowana.
Msg 208, poziom 16, stan 0 Niepoprawna nazwa obiektu „#Pivoted”. Wynika to z faktu, że #Pivoted jest własnością połączenia Dynamic SQL. Więc ostatnia instrukcja
zawodzi.
Jednym ze sposobów na rozwiązanie tego problemu jest upewnienie się, że wszystkie odwołania do #Pivoted pochodzą z samego zapytania dynamicznego:
źródło
Zrobiłbym następujące
Utwórz (przekonwertuj SP na) UDF (wartość tabeli UDF).
select * into #tmpBusLine from dbo.UDF_getBusinessLineHistory '16 Mar 2009'
źródło