niedziela, 8 maja 2011

globalna identyfikacja tabeli tymczasowej

Lokalne tabele tymczasowe  są widoczne tylko dla ich twórców podczas tego samego połączenia z instancją SQL Server na którym zostały utworzone, są usuwane gdy użytkownik odłączy się od instancji.
Tak mniej więcej piszą w BOL, dodatkowo wszyscy wiemy że w ramach tej samej sesji nie można założyć dwóch tabel o takiej samej nazwie.

Niewiadomo jak serwer radzi sobie z rozpoznawaniem, która tabela jest przypisana do którego SPIDu, w skali instancji niepowtarzalność gwarantuje 12 znaków HEX, które są zwiększającym się licznikiem.
Licznik ten zeruje się przy każdym restarcie serwera, ciekawe co się stanie jeżeli w czasie nieprzerwanej pracy serwera założymy więcej niż 281474976710655 tabel tymczasowych, czyli FFFFFFFFFFFF.

Zróbmy sobie mały test

USE tempdb
GO
SELECT @@SPID

CREATE TABLE #a (i INT);
GO
DECLARE @q VARCHAR(max)

SET @q='SELECT @@SPID; CREATE TABLE #a (i INT);
SELECT id ,NAME
FROM  tempdb.sys.sysobjects
WHERE xtype =''U'' AND NAME LIKE ''#a%''
'
EXEC (@q);
GO
SELECT id ,NAME
FROM  tempdb.sys.sysobjects
WHERE xtype ='U' AND NAME like '#a%'

------
55

------
55

id          NAME
----------------------------------
1253579504  #a__...___000000000001
1269579561  #a__...___000000000002

id          NAME
----------------------------------
1253579504  #a__...___000000000001

Prosty test pokazuje, że tabela nie jest niszczona po odłączeniu a może być tez podczas jego trwania i w ramach jednej sesji mogą istnieć tabele o takiej samej nazwie.

2 komentarze:

  1. To tylko scope :-) A najlepszy jest zapisek z BOL: "(...) if a query references a temporary table and two temporary tables with the same name exist at that time, it is not defined which table the query is resolved against (...)". Czyli po mojemu - "sam jesteś sobie winien, zły człowieku" :-D

    OdpowiedzUsuń
  2. BTW, ta liczba 281474976710655 tabel tymczasowych może być ciut trudna do osiągnięcia nawet, jakbyśmy chcieli w ogóle tyle tabel tymczasowych założyć ;-)

    SPID to smallint (raptem 32k z groszem), poziomów zagnieżdżenia mamy do 32(gdyby chcieć używać EXEC).

    No i widzę jeszcze jeden problem - object_id jest typu int, co oznacza, że obiektów w jednej bazie założysz co najwyżej jakieś 4 mld z hakiem ;-)

    OdpowiedzUsuń