Tenho uma pergunta sobre uma parte da documentação sobre tabelas temporárias que li recentemente no TechNet . O quarto parágrafo da seção Tabelas Temporárias nessa página tem a seguinte redação:
Se uma tabela temporária for criada com uma restrição nomeada e a tabela temporária for criada no escopo de uma transação definida pelo usuário, apenas um usuário por vez poderá executar a instrução que cria a tabela temporária. Por exemplo, se um procedimento armazenado criar uma tabela temporária com uma restrição de chave primária nomeada, o procedimento armazenado não poderá ser executado simultaneamente por vários usuários.
Trabalho em um ambiente em que fazemos uso significativo de alguns procedimentos armazenados que usam tabelas temporárias indexadas e nunca encontramos um problema em que os usuários precisavam esperar que uma execução fosse concluída antes do início da próxima. Espero que continue assim, mas estou preocupado que isso possa se tornar um problema se essa advertência não for entendida adequadamente.
Especificamente, não estou claro sobre os seguintes pontos:
- Isso se aplica apenas a tabelas temporárias globais ou também locais? Parece estranho que uma tabela que não esteja visível fora da sessão (como no último caso) impeça a execução simultânea de outra sessão.
- O que qualifica como uma "restrição nomeada"? Nem todas as restrições têm nomes (mesmo que sejam geradas pelo sistema)? Isso se refere a restrições com um alias definido pelo usuário? Isso parece um fraseado ruim para mim.
- "Múltiplos usuários" realmente significa várias sessões? Esses procedimentos são chamados por meio de nosso aplicativo usando uma conta de serviço única; portanto, 99,9% das chamadas para nossos scripts são feitas no banco de dados por essa conta única (e não estou preocupado com a ligação ocasional que um administrador pode fazer no back-end). Se a conta de serviço puder executar o sproc em várias sessões simultaneamente, esse problema é discutível para meus propósitos.
fonte
Respostas:
Penso nisso como você não pode ter nomes duplicados
tempdb.sys.key_constraints
. Aqui está o que há nessa exibição de metadados em um dos meus servidores:Todos os nomes ímpares que terminam com
_6E...
eram nomes gerados automaticamente pelo SQL Server. Eles não têm restrições de nome porque eu não lhes dei um nome explicitamente ao criá-las. O SQL Server gera um nome de restrição nos bastidores que, em teoria, evita colisões de nomes.Se eu tentar criar a tabela a seguir em duas sessões diferentes:
Aquele que executa o segundo lança um erro:
Verificando a visualização novamente:
Se eu tentar criar a tabela a seguir em duas sessões, não há problema:
Aqui está a exibição de metadados:
Apenas para responder suas perguntas diretamente: a parte que você citou se aplica a tabelas temporárias locais e globais, uma restrição nomeada é aquela na qual você deliberadamente nomeia um nome e vários usuários significam várias sessões.
fonte
Isso se aplica às tabelas temporárias locais.
A diferença entre restrições nomeadas e não nomeadas é esta:
Deixar as restrições de nome do sistema torna extremamente improvável que ocorra uma colisão. Neste exemplo, se você abrir duas janelas no SSMS, poderá criar
#t1
nas duas, mas não#t2
.As tabelas temporárias globais são compartilhadas por todos os usuários, portanto, você precisa lidar com as coisas de maneira diferente. Eles não são "destruídos" até a última sessão ser concluída com eles, portanto, você precisa garantir que, quando os usuários os acessarem, eles possam acessar apenas seus dados. Às vezes, isso é feito pelo SPID, outras vezes, por um valor de hash. Depende de como a tabela temporária global é usada.
Tipicamente para tabelas temporárias globais, procedimentos armazenados irá verificar para ver se eles existem, e só então criá-los se o
OBJECT_ID()
éNULL
.Múltiplos usuários significa várias sessões. O nome de login não tem nada a ver com isso. Se George executar
sp_something @i = 1
e Gina executarsp_something @i = 2
, não importa se os dois estão conectados comoUser1
, eles terão SPIDs diferentes.fonte