Digamos que temos 2 consultas completamente diferentes, que fazem referência a uma tabela temporária com o mesmo nome:
consulta um .... opera em: #tempTableName
consulta dois .... opera em: #tempTableName
Eu pesquisei isso e descobri que "#temp é uma tabela temporária local e, portanto, não é visível para outras conexões", no entanto, não tenho certeza do que uma conexão realmente significa em profundidade no contexto de consultas SQL. O SQL considera que há uma 'conexão' separada para cada consulta separada que é executada ou uma conexão é compartilhada de alguma forma?
Especificamente, minha pergunta é "o que está acontecendo se as duas consultas no meu cenário estão sendo acessadas pelo mesmo login", por exemplo, vários aplicativos .NET estão usando a mesma cadeia de conexão .NET e acessando simultaneamente o banco de dados. Eles vão acessar potencialmente a mesma tabela temporária se ambas as consultas no meu cenário estiverem sendo executadas simultaneamente? E as fechaduras? Preciso fazer alguma coisa para evitar o acesso indesejado durante as operações na mesa?
Eu olhei para esta resposta, https://stackoverflow.com/questions/466947/are-temporary-tables-thread-safe , no entanto, eu realmente preciso de algo como uma explicação 'fingir que tenho 6 anos' para que eu Estou muito claro sobre o que está acontecendo no meu cenário hipotético em termos de exatamente como as consultas SQL estão utilizando conexões e determinando acesso exclusivo etc. Quaisquer diagramas ou ponteiros para recursos que possam me dar um comando completo disso seria ótimo!
Objetos temporários locais são separados por Session. Se você tiver duas consultas em execução simultaneamente, elas são claramente duas sessões completamente separadas e você não precisa se preocupar. O Login não importa. E se você estiver usando o pool de conexões, isso também não importará. Objetos temporários locais (tabelas com mais frequência, mas também procedimentos armazenados) estão protegidos de serem vistos por outras sessões.
Embora seu código tenha um nome único e comum para os objetos temporários locais, o SQL Server anexa uma string exclusiva a cada nome de objeto por cada sessão (e, se necessário, por cada subprocesso) para mantê-los separados. Você pode ver isso executando as seguintes consultas no SSMS:
Você verá algo como o seguinte para o nome (removi a maioria dos sublinhados do meio do nome para evitar a necessidade de rolar aqui):
Em seguida, sem fechar essa guia de consulta, abra uma nova guia de consulta e cole essas mesmas 2 consultas e execute-as. Agora você deve ver algo como o seguinte:
Portanto, cada vez que seu código fizer referência a
#T
, o SQL Server o traduzirá para o nome adequado com base na sessão. Tudo é tratado auto-magicamente :-).Para ilustrar este ponto. Trabalhei em sistemas altamente transacionais (milhares de transações por segundo) e eram aplicativos web SaaS (Software as a Service) rodando 24 horas por dia, 7 dias por semana. Todo o código T-SQL estava em Stored Procedures (ou seja: mesmo nome de tabela temporária local para cada execução desse código) e fizemos um bom uso das tabelas temporárias locais. Sendo um aplicativo da web, o Login foi o mesmo em quase todas as conexões e definitivamente usamos o pool de conexões. Nunca tivemos problemas para indicar qualquer acesso entre sessões de objetos temporários locais com o mesmo nome. E, francamente, ficaríamos chocados e usaríamos nosso contrato de suporte com a Microsoft para consertá-lo se isso acontecesse.
Pontos adicionais a serem lembrados em relação às tabelas temporárias locais:
Embora seus nomes sejam exclusivos, seus objetos dependentes não são. Você não pode criar Triggers ou Chaves Estrangeiras em tabelas temporárias, portanto, trata-se realmente de Chaves Primárias, Restrições de Verificação e Restrições Padrão. Isso significa que nomear uma Chave Primária
#PK_#T
não a torna um nome exclusivo com um ID exclusivo de bastidores anexado ao nome. Se você tentar isso, obterá "Não é possível criar objeto. O objeto já existe". erros (bem, assumindo várias execuções simultâneas neste mesmo código). Portanto, se você precisar de qualquer um desses 3 tipos de objeto para uma tabela temporária local, crie o(s) objeto(s) dependente(s) embutido(s) para que eles obtenham nomes gerados pelo sistema que serão exclusivos e não entrarão em conflito entre as Sessões.Você não precisa se preocupar com nomes de índice, pois eles já estão separados por
[object_id]
.Dado que você obtém "Não é possível criar objeto. O objeto já existe". erros ao criar objetos dependentes nomeados, isso traz um bom ponto que é mais frequentemente esquecido em relação a essa questão de "os objetos temporários locais são completamente isolados por sessão": Se as tabelas temporárias locais pudessem ser vistas por outras sessões, a
CREATE TABLE
instrução obteria um erro, certo?Uma nuance de tabelas temporárias locais (que também é um contraponto solto para #2 acima) é que se você referenciar uma tabela temporária local em um subprocesso (ou seja,
EXEC
) que foi criado antes do início desse subprocesso, ela poder ver (e até modificar) essa tabela temporária local. NO ENTANTO, se esse subprocesso criar outra tabela temporária com o mesmo nome, haverá dois objetos, com IDs exclusivos separados anexados ao final, que podem ser acessados por meio do nome abreviado. Lembro-me de ler em algum lugar que não há garantia de que a referência#name
no subprocesso sempre resolverá para a versão desse objeto que foi criado no subprocesso. Portanto, é melhor ter alguma exclusividade de nomes de tabelas temporárias locais entre Stored Procedures que tenham qualquer possibilidade de serem executadas em uma cadeia de chamadas de Stored Procedure aninhadas.