Tabelas do SQL Server: qual é a diferença entre @, # e ##?

89

No SQL Server, qual é a diferença entre uma tabela @, uma tabela # e uma tabela ##?

Craig Schwarze
fonte

Respostas:

114

#table refere-se a uma tabela temporária local (visível apenas para o usuário que a criou).

##table refere-se a uma tabela temporária global (visível para todos os usuários).

@variableName refere-se a uma variável que pode conter valores dependendo de seu tipo.

Arnkrishn
fonte
29
Sua definição de #table não está totalmente correta. Não se limita ao usuário, mas sim à conexão. Se um usuário tiver várias conexões, ele só ficará visível para a conexão que criou a #table inicialmente.
Davin Studer
@DavinStuder ofereceu um esclarecimento crucial. A distinção entre uma tabela visível para o usuário e uma tabela visível apenas na conexão atual é muito importante.
mirzmaster
@DavinStuder como visualizar múltiplas conexões para o usuário? a mesma string de conexão?
Kiquenet
25

Dê uma olhada em

Adriaan Stander
fonte
4
Percebi que isso é há muito tempo, mas como esta é uma resposta apenas de link (e o primeiro link está inativo), ela poderia ser atualizada com as principais conclusões de cada um dos links?
Mike Guthrie
7

#e as ##tabelas são tabelas reais representadas no banco de dados temporário. Essas tabelas podem ter índices e estatísticas e podem ser acessadas em sprocs em uma sessão (no caso de uma tabela temporária global, ela está disponível em todas as sessões).

O @table é uma variável de tabela.

Para mais informações: http://www.sqlteam.com/article/temporary-tables

Chorão
fonte
4
E a variável da tabela também residirá no banco de dados tempDB, se seu tamanho for muito grande para ser armazenado na memória.
marc_s
6

Eu me concentraria nas diferenças entre #table e @table. ## table é uma tabela temporária global e, para registro, em mais de 10 anos de uso do SQL Server, ainda não encontrei um caso de uso válido. Tenho certeza que alguns existem, mas a natureza do objeto o torna IMHO altamente inutilizável.

A resposta a @whiner por @marc_s é absolutamente verdadeira: é um mito prevalente que as variáveis ​​de tabela sempre vivem na memória. Na verdade, é bastante comum que uma variável de tabela vá para o disco e opere como uma tabela temporária.

De qualquer forma, sugiro ler sobre o conjunto de diferenças seguindo os links apontados por @Astander. A maior parte da diferença envolve limitações sobre o que você não pode fazer com as variáveis ​​@table.

Aaron Bertrand
fonte
Eu tenho 5 procedimentos armazenados separados que realizam diferentes partes de um cálculo e geram um único resultado. Para auditoria, quero ver os valores intermediários e o auditor também. Ajustei meus procedimentos para despejar alguns em uma tabela ## Temp para que ambos possamos visualizá-los, mas eles não são mantidos (eles são necessários apenas durante as auditorias). Existe um caso de uso válido para você (IMHO!).
RyanfaeScotland
@Ryan por que ## Table é válido quando você poderia ter usado dbo.Table? Não considero um caso de uso válido quando tudo o que você fez foi evitar digitar uma instrução DROP.
Aaron Bertrand
4
Não quero dar ao auditor permissões DROP no meu banco de dados. Eu também não quero ter que voltar e arrumar depois que ele terminar. Com uma tabela temporária, ele pode executar a consulta quantas vezes quiser e sei que quando ele terminar, ele não estará deixando uma pegada no banco de dados.
RyanfaeScotland
4
CREATE TABLE #t

Cria uma tabela que só é visível nessa CONEXÃO e durante essa CONEXÃO, o mesmo usuário que cria outra conexão não poderá ver a tabela #t da outra conexão.

CREATE TABLE ##t

Cria uma tabela temporária visível para outras conexões. Mas a tabela é descartada quando a criação da conexão é encerrada.

Markus
fonte
SqlConnection.Open()com a mesma string de conexão é A mesma CONEXÃO ?
Kiquenet
2
não, é uma conexão com o mesmo banco de dados, mas quase certamente não é a mesma conexão.
Markus
0

se você precisar de uma tabela temporária global exclusiva, crie a sua própria com um prefixo / sufixo de identificador exclusivo e elimine a execução posterior se um if object_id (.... A única desvantagem é usar sql dinâmico e precisa ser eliminado explicitamente.

Schmed
fonte