Tablas de SQL Server: ¿cuál es la diferencia entre @, # y ##?

90

En SQL Server, ¿cuál es la diferencia entre una tabla @, una tabla # y una tabla ##?

Craig Schwarze
fuente

Respuestas:

114

#table se refiere a una tabla temporal local (visible solo para el usuario que la creó).

##table se refiere a una tabla temporal global (visible para todos los usuarios).

@variableName se refiere a una variable que puede contener valores dependiendo de su tipo.

Arnkrishn
fuente
31
Tu definición de #tabla no es del todo correcta. No se limita al usuario sino a la conexión. Si un usuario tiene varias conexiones, solo será visible para la conexión que creó la #tabla en primer lugar.
Davin Studer
@DavinStuder ha ofrecido una aclaración crucial. La distinción entre una tabla visible para el usuario frente a una tabla visible solo en la conexión actual es muy importante.
mirzmaster
@DavinStuder ¿cómo ver múltiples conexiones para el usuario? la misma cadena de conexión?
Kiquenet
24

Mira esto

Adriaan Stander
fuente
4
Me doy cuenta de que esto es de hace mucho tiempo, pero dado que esta es una respuesta de solo enlace (y el primer enlace está muerto), ¿podría actualizarse con las conclusiones principales de cada uno de los enlaces?
Mike Guthrie
7

#y las ##tablas son tablas reales representadas en la base de datos temporal. Estas tablas pueden tener índices y estadísticas, y se puede acceder a ellas a través de sprocs en una sesión (en el caso de una tabla temporal global, está disponible en todas las sesiones).

@Table es una variable de tabla.

Para más: http://www.sqlteam.com/article/temporary-tables

llorón
fuente
4
Y la variable de la tabla también vivirá en la base de datos tempDB, si su tamaño es demasiado grande para guardarlo en la memoria.
marc_s
5

Me centraría en las diferencias entre #table y @table. ## table es una tabla temporal global y, para que conste en más de 10 años de uso de SQL Server, todavía no he encontrado un caso de uso válido. Estoy seguro de que existen algunos, pero la naturaleza del objeto lo hace altamente inutilizable en mi humilde opinión.

La respuesta a @whiner por @marc_s es absolutamente cierta: es un mito prevaleciente que las variables de la tabla siempre viven en la memoria. En realidad, es bastante común que una variable de tabla vaya al disco y funcione como una tabla temporal.

De todos modos, sugiero leer sobre el conjunto de diferencias siguiendo los enlaces señalados por @Astander. La mayor parte de la diferencia implica limitaciones sobre lo que no puede hacer con las variables @table.

Aaron Bertrand
fuente
Tengo 5 procedimientos almacenados separados que realizan diferentes partes de un cálculo y generan un solo resultado. Para la auditoría, quiero ver valores intermedios y el auditor también. Ajusté mis procedimientos para descargar algunos en una tabla ## Temp para que ambos podamos verlos, pero no se conservan (solo se necesitan durante las auditorías). Hay un caso de uso válido para ti (¡en mi humilde opinión!).
RyanfaeScotland
@Ryan, ¿por qué ## Table es válida cuando podrías haber usado dbo.Table? No lo considero un caso de uso válido cuando todo lo que ha hecho es salvarse de escribir una declaración DROP.
Aaron Bertrand
4
No quiero darle al auditor permisos DROP en mi base de datos. Tampoco quiero tener que volver y ordenar después de que él haya terminado. Con una tabla temporal, puede ejecutar la consulta con la frecuencia que quiera y sé que cuando haya terminado, no dejará una huella en la base de datos.
RyanfaeScotland
4
CREATE TABLE #t

Crea una tabla que solo es visible en y durante esa CONEXIÓN, el mismo usuario que crea otra conexión no podrá ver la tabla #t de la otra conexión.

CREATE TABLE ##t

Crea una tabla temporal visible para otras conexiones. Pero la tabla se descarta cuando finaliza la conexión de creación.

Markus
fuente
SqlConnection.Open()con la misma cadena de conexión es la misma CONEXIÓN ?
Kiquenet
2
no, es una conexión a la misma base de datos, pero es casi seguro que no sea la misma conexión.
Markus
0

si necesita una tabla temporal global única, cree la suya propia con un prefijo / sufijo de identificador único y elimine la ejecución de la publicación si un if object_id (.... El único inconveniente es usar SQL dinámico y debe eliminarlo explícitamente.

Schmed
fuente