Tabele programu SQL Server: jaka jest różnica między @, # i ##?

90

Jaka jest różnica między tabelą @, tabelą # i tabelą ## w SQL Server?

Craig Schwarze
źródło

Odpowiedzi:

114

#table odnosi się do lokalnej (widocznej tylko dla użytkownika, który ją utworzył) tabeli tymczasowej.

##table odnosi się do globalnej (widocznej dla wszystkich użytkowników) tabeli tymczasowej.

@variableName odnosi się do zmiennej, która może przechowywać wartości w zależności od jej typu.

Arnkrishn
źródło
31
Twoja definicja #table nie jest całkowicie poprawna. Nie ogranicza się do użytkownika, ale raczej do połączenia. Jeśli użytkownik ma wiele połączeń, będzie to widoczne tylko dla połączenia, które utworzyło tabelę # w pierwszej kolejności.
Davin Studer
@DavinStuder przedstawił kluczowe wyjaśnienie. Rozróżnienie między tabelą widoczną dla użytkownika a tabelą widoczną tylko w bieżącym połączeniu jest bardzo ważne.
mirzmaster
@DavinStuder jak wyświetlić wiele połączeń dla użytkownika? te same parametry połączenia?
Kiquenet
24

Spójrz na

Adriaan Stander
źródło
4
Zdaję sobie sprawę, że pochodzi to od dawna, ale skoro jest to odpowiedź zawierająca tylko łącze (a pierwszy link jest martwy), czy można ją zaktualizować, uwzględniając główne wnioski z każdego łącza?
Mike Guthrie,
7

#a ##tabele to rzeczywiste tabele reprezentowane w tymczasowej bazie danych. Tabele te mogą mieć indeksy i statystyki i można uzyskać do nich dostęp poprzez sprocs w sesji (w przypadku globalnej tabeli tymczasowej jest ona dostępna między sesjami).

@Table to zmienna tabeli.

Więcej: http://www.sqlteam.com/article/temporary-tables

jęczeć
źródło
4
Zmienna tabeli będzie również znajdować się w bazie danych tempDB, jeśli jej rozmiar jest zbyt duży, aby przechowywać go w pamięci.
marc_s
5

Skupiłbym się na różnicach między #table i @table. ## table jest globalną tabelą tymczasową i przez ponad 10 lat używania SQL Server nie znalazłem jeszcze ważnego przypadku użycia. Jestem pewien, że niektóre istnieją, ale natura obiektu sprawia, że ​​jest on wysoce bezużyteczny IMHO.

Odpowiedź na @whiner autorstwa @marc_s jest absolutnie prawdziwa: rozpowszechnionym mitem jest to, że zmienne tabeli zawsze żyją w pamięci. W rzeczywistości dość często zmienna tabeli trafia na dysk i działa podobnie jak tabela tymczasowa.

W każdym razie proponuję zapoznać się z zestawem różnic, podążając za linkami wskazanymi przez @Astander. Większość różnic dotyczy ograniczeń dotyczących tego, czego nie można zrobić ze zmiennymi @table.

Aaron Bertrand
źródło
Mam 5 oddzielnych procedur składowanych, które wykonują różne części obliczenia i wyświetlają pojedynczy wynik. Jeśli chodzi o audyt, chcę zobaczyć wartości pośrednie, podobnie jak audytor. Dostosowałem swoje procedury, aby zrzucić niektóre z nich do tabeli ## Temp, abyśmy mogli je przeglądać, ale nie są one zachowywane (są potrzebne tylko podczas audytów). Jest dla ciebie ważny przypadek użycia (IMHO!).
RyanfaeScotland
@Ryan, dlaczego ## Tabela jest ważna, skoro można było użyć dbo.Table? Nie uważam tego za ważny przypadek użycia, gdy wszystko, co zrobiłeś, to uratowanie się przed wpisaniem instrukcji DROP.
Aaron Bertrand
4
Nie chcę dawać audytorowi DROP uprawnień do mojej bazy danych. Nie chcę też wracać i sprzątać po jego zakończeniu. Dzięki tabeli tymczasowej może uruchamiać zapytanie tak często, jak mu się podoba, a ja wiem, że po zakończeniu nie pozostawia śladu w bazie danych.
RyanfaeScotland
4
CREATE TABLE #t

Tworzy tabelę, która jest widoczna tylko w czasie tego POŁĄCZENIA i podczas tego POŁĄCZENIA ten sam użytkownik, który tworzy inne połączenie, nie będzie mógł zobaczyć tabeli #t z innego połączenia.

CREATE TABLE ##t

Tworzy tymczasową tabelę widoczną dla innych połączeń. Ale tabela jest usuwana po zakończeniu tworzenia połączenia.

Markus
źródło
SqlConnection.Open()z tymi samymi parametrami połączenia jest to samo POŁĄCZENIE ?
Kiquenet
2
nie, jest to połączenie z tą samą bazą danych, ale prawie na pewno nie to samo połączenie.
Markus
0

jeśli potrzebujesz unikalnej globalnej tabeli tymczasowej, stwórz własną z przedrostkiem / sufiksem Uniqueidentifier i porzuć wykonanie po wykonaniu if object_id (.... Jedyną wadą jest użycie Dynamic sql i musisz jawnie upuścić.

Schmed
źródło