none
Tablas temporales locales y globales

    Pregunta

  • Hola, como estan? Estoy creando una tabla temporal, en ella voy a almacenar tuplas que ire comparando con una tabla de la BD, con la finalidad de agregar las tuplas que no esten repetidas. Esto es para lograr la solucion propuesta en:

    http://social.msdn.microsoft.com/Forums/es-ES/sqlserveres/thread/52079950-d0c6-4f91-8ebc-59651eb29e64

    Tengo algo asi en mi codigo

    try {

     

     SqlDataReader reader = null;

     SqlCommand query = new SqlCommand("CREATE TABLE ##METRIC (period DATE NOT NULL,  APP_USER_login VARCHAR(20) NOT NULL, country VARCHAR(100) NOT NULL, manager  VARCHAR(30) NOT NULL); INSERT INTO ##METRIC (period, APP_USER_login, country, manager) VALUES( @date, '" + GlobalClass.UserName + "', '" + country + "', '" + manager + "'); SELECT country, period, manager FROM ##METRIC;", sqlConex);

            query.Parameters.Add("@date", System.Data.SqlDbType.Date).Value = Convert.ToDateTime(dateS);

            reader = query.ExecuteReader();

            while (reader.Read())

             {

     try

                    {

                     SqlDataReader reader1 = null;

                             SqlCommand selectMetric = new SqlCommand("SELECT country, period FROM METRIC;", sqlConex);

                              reader1 = selectMetric.ExecuteReader();

                              while (reader1.Read())

                              {

                               if (reader.GetString(0) == reader1.GetString(0) && reader.GetDateTime(1).ToShortDateString() == reader1.GetDateTime(1).ToShortDateString())

                                {

                                try

                                 {

                                     SqlCommand delete = new SqlCommand("DELETE FROM ##METRIC WHERE period = '" + reader.GetDateTime(1).ToShortDateString()+"'  AND country = '" + reader.GetString(0) + "';", sqlConex);

                                      delete.ExecuteNonQuery();

                                   }

                                   catch(Exception e)

                                    {

                                     MessageBox.Show(e.ToString());

                                     }

     }

    //con sus respectivos catch

    El problema es que cuando corro la aplicación me genera el siguiente error:

     

    System.Data.SqlClient.SqlException(0x80131904) : Ya hay un objeto con el nombre ##METRIC en la Base de Datos.

    Yo no encuentro esa tabla. He reiniciado el Visual Studio y el SQL SERVER MANAGEMENT STUDIO y nada! Ma sale el mismo error.

     

    Por favor ayudenme!

     


    • Cambiado Willy TaverasModerator sábado, 16 de abril de 2011 23:43 Pregunta de SQL Server no C# (De:Lenguaje C#)
    viernes, 15 de abril de 2011 20:57

Respuestas

  • A ver, para que entiendas mejor lo que te esta pasando.

    Las tablas temporales son consideradas tablas regulares, y estas se almacenan automáticamente en la base de datos de tempdb. Existen dos tipos de tablas temporales: Globales y Locales: las tablas temporales Locales se escriben anteponiendo el símbolo # y tablas temporales Globales con el doble símbolo ##.

    Las tablas temporales Locales están disponibles para usarse por cada conexión actual del usuario que los cree. Varias conexiones pueden crear una tabla temporal con mismo nombre, esto solo para para tablas temporales Locales sin causar conflictos. La representación interna de la tabla local tiene un nombre único, para no estar en conflicto con otras tablas temporales con el mismo nombre creado por otras conexiones en la tempdb.
    Las tablas temporales locales son eliminadas con el comando DROP o se eliminan automáticamente de memoria cuando se cierra la conexión del usuario.

    Si finalmente decides usar tablas temporales locales asegurate si estas haciendo nuevas conexiones, cada vez que reconectes la tabla no existirá aunque la crees con el mismo nombre para la nueva sesión, de ahí tus lios y nal entendimientos.

    Las tablas temporales Globales tienen un alcance diferente al de las tablas temporalesLocales. Una vez que una conexión crea una tabla temporal Global, cualquier usuario con permisos adecuados sobre la base de datos puede acceder a la tabla. A diferencia de tablas temporales Locales, no se pueden crear versiones simultáneas de una tabla temporal Global, ya que esto generará un conflicto de nombres.
    Las tablas temporales Globales de eliminan explícitamente de SQL Server ejecutando DROP ##TABLE. También se eliminan automáticamente después de que se cierra la conexión que la creo, la tabla temporal Global no es referenciada por otras conexiones, pero es muy raro ver que se utilicen tablas temporales Globales en bases de datos en producción.
    Es importante considerar cuando una tabla va o debe ser compartida a través de conexiones, se debe crear una tabla real, en lugar de una tabla temporal Global. No obstante, SQL Server ofrece esto como una opción.

     


     Norman M. Pardell 

    ||Microsoft Certified IT Professional|| Database Administrator. Database Developer. SQL Server 2008

    • Marcado como respuesta suhi_22 martes, 26 de abril de 2011 15:43
    domingo, 24 de abril de 2011 14:24

Todas las respuestas

  • para remover una tabla temporal o norma tienes que usar

    DROP TABLE tempdb..##METRIC

    verifica antes si la tabla temporal ya existe si no existe la creas caso contrario no la creas y solo la usas

    IF OBJECT_ID(N'tempdb..##METRIC', N'U') IS NOT NULL

    DROP TABLE tempdb..##METRIC

     

    Salu2


    Marvin E. Pineda

    ComboBoxMultiColumns

    Marvin's Blog
    San Pedro Sula
    Honduras. C.A.


    Aún el necio cuando calla, es contado por sabio.


    viernes, 15 de abril de 2011 21:06
    Moderador
  • ademas, si la tabla temporal la quieres solo para solucionar el problema, no crees una tabla temporal Global crea una tabla temporal de session asi cuando cierres la conexión esta deberia de borrarse sola, para crear una temporal de session solo seria con #METRIC <- tabla temporal de session y ##METRIC <- tabla temporal Global

    Marvin E. Pineda

    ComboBoxMultiColumns

    Marvin's Blog
    San Pedro Sula
    Honduras. C.A.


    Aún el necio cuando calla, es contado por sabio.

    viernes, 15 de abril de 2011 21:12
    Moderador
  • Marvin, cuando intento hacer 

    DROP TABLE tempdb..##METRIC

    por el SQL SERVER me da este error:


    Se omitió el nombre de la base de datos 'tempdb'. Se hace referencia al objeto en tempdb.

    Msg 3701, Level 11, State 5, Line 1

    No se puede quitar el tabla '##METRIC' porque no existe o el usuario no tiene permiso.

     

    También hice la prueba con #METRIC, pero siempre me da ese problema :-(

    viernes, 15 de abril de 2011 21:28

  • Marvin, cuando intento hacer 

    DROP TABLE tempdb..##METRIC

    por el SQL SERVER me da este error:


     

    Se omitió el nombre de la base de datos 'tempdb'. Se hace referencia al objeto en tempdb.

    Msg 3701, Level 11, State 5, Line 1

    No se puede quitar el tabla '##METRIC' porque no existe o el usuario no tiene permiso.

     

    También hice la prueba con #METRIC, pero siempre me da ese problema :-(

     

     

    primero la debes de crear o validar que exista

    IF OBJECT_ID(N'tempdb..##METRIC', N'U') IS NOT NULL

    DROP TABLE tempdb..##METRIC

     


    Marvin E. Pineda

    ComboBoxMultiColumns

    Marvin's Blog
    San Pedro Sula
    Honduras. C.A.


    Aún el necio cuando calla, es contado por sabio.

    viernes, 15 de abril de 2011 21:30
    Moderador
  • Marvin, cuando intento hacer 

    DROP TABLE tempdb..##METRIC

    por el SQL SERVER me da este error:


     

    Se omitió el nombre de la base de datos 'tempdb'. Se hace referencia al objeto en tempdb.

    Msg 3701, Level 11, State 5, Line 1

    No se puede quitar el tabla '##METRIC' porque no existe o el usuario no tiene permiso.

     

    También hice la prueba con #METRIC, pero siempre me da ese problema :-(

     


    ya encontre porque el mensaje, prueba de esta manera

    IF OBJECT_ID(N'tempdb..##METRIC', N'U') IS NOT NULL
        DROP TABLE ##METRIC

     

    como veras en la linea DROP TABLE ya no incluyo el nombre de la base de datos tempdb

    Salu2,


    Marvin E. Pineda

    ComboBoxMultiColumns

    Marvin's Blog
    San Pedro Sula
    Honduras. C.A.


    Aún el necio cuando calla, es contado por sabio.

    viernes, 15 de abril de 2011 21:43
    Moderador
  • Para eliminar la tabla temporar puede hacerlo de esta forma

    IF EXISTS ( SELECT * FROM sys.tables WHERE sys.tables.name = N'##METRIC') DROP TABLE ##METRIC;

    Es practicamente parecido a la alternativa que te plantea Marvin E. Pineda, ambas obtienen el mismo resultado.

    Otra observacion es que como esta trabajando con dos tabla para obtener los valores no duplicado podria utilizar los operadores EXCEPT e INTERSECT (Transact-SQL) para devolver valores distintos al comparar los resultados de dos consultas.

    EXCEPT devuelve los valores distintos de la consulta izquierda que no se encuentran en la consulta derecha.

    INTERSECT devuelve los valores distintos devueltos por las consultas situadas a los lados izquierdo y derecho del operando INTERSECT.


    Angel R. Jimenez G.
    Software Development
    Santo Domingo
    Republica Dominicana
    sábado, 16 de abril de 2011 8:39
  • Hola, ok, tengo este codigo:
      
     try
        {
         SqlDataReader reader = null;
            SqlCommand query = new SqlCommand("IF OBJECT_ID(N'tempdb..#METRIC', N'U') IS NOT NULL DROP TABLE #METRIC ELSE CREATE TABLE #METRIC (period DATE NOT NULL, APP_USER_login VARCHAR(20) NOT NULL, country VARCHAR(100) NOT NULL, manager VARCHAR(30) NOT NULL); INSERT INTO #METRIC VALUES('" +Convert.ToDateTime(dateS).ToShortDateString() + "', '" + GlobalClass.UserName + "', '" + country + "', '" + manager + "');
    IF EXISTS (SELECT country, period, manager FROM #METRIC) SELECT country, period, manager FROM #METRIC EXCEPT SELECT country, period, manager FROM METRIC;", sqlConex); 
             reader = query.ExecuteReader();
                    while (reader.Read())
                    {
                    try 
                    {
                     SqlCommand insert = new SqlCommand("INSERT INTO METRIC(period, APP_USER_login, country, manager) VALUES('" + reader.GetDateTime(1).ToShortDateString() + "', '" + GlobalClass.UserName + "','" + reader.GetString(0) + "','" + reader.GetString(2) + "');", sqlConex);
                                    insert.ExecuteNonQuery();
                     }
                     catch(Exception e)
                     {
                     MessageBox.Show(e.ToString());
                     }
     catch(Exception e)
             {
                  MessageBox.Show(e.ToString());
             }
    Pero me da un error:
    "El nombre de objeto #METRIC no es válido"
    Sin embargo, me inserta los registros en la tabla METRIC, pero me da ese error por cada registro que trato de insertar.
    ¿Cómo puedo resolver esto?
    Gracias :-)
    lunes, 18 de abril de 2011 14:25
  • Hola.

    ¿Resolviste el problema?


    Alberto López Grande
    SQL Server MVP
    Visita mi blog en http://qwalgrande.blogspot.es/ Sígueme en twitter en http://twitter.com/qwalgrande

    domingo, 24 de abril de 2011 10:23
    Moderador
  • A ver, para que entiendas mejor lo que te esta pasando.

    Las tablas temporales son consideradas tablas regulares, y estas se almacenan automáticamente en la base de datos de tempdb. Existen dos tipos de tablas temporales: Globales y Locales: las tablas temporales Locales se escriben anteponiendo el símbolo # y tablas temporales Globales con el doble símbolo ##.

    Las tablas temporales Locales están disponibles para usarse por cada conexión actual del usuario que los cree. Varias conexiones pueden crear una tabla temporal con mismo nombre, esto solo para para tablas temporales Locales sin causar conflictos. La representación interna de la tabla local tiene un nombre único, para no estar en conflicto con otras tablas temporales con el mismo nombre creado por otras conexiones en la tempdb.
    Las tablas temporales locales son eliminadas con el comando DROP o se eliminan automáticamente de memoria cuando se cierra la conexión del usuario.

    Si finalmente decides usar tablas temporales locales asegurate si estas haciendo nuevas conexiones, cada vez que reconectes la tabla no existirá aunque la crees con el mismo nombre para la nueva sesión, de ahí tus lios y nal entendimientos.

    Las tablas temporales Globales tienen un alcance diferente al de las tablas temporalesLocales. Una vez que una conexión crea una tabla temporal Global, cualquier usuario con permisos adecuados sobre la base de datos puede acceder a la tabla. A diferencia de tablas temporales Locales, no se pueden crear versiones simultáneas de una tabla temporal Global, ya que esto generará un conflicto de nombres.
    Las tablas temporales Globales de eliminan explícitamente de SQL Server ejecutando DROP ##TABLE. También se eliminan automáticamente después de que se cierra la conexión que la creo, la tabla temporal Global no es referenciada por otras conexiones, pero es muy raro ver que se utilicen tablas temporales Globales en bases de datos en producción.
    Es importante considerar cuando una tabla va o debe ser compartida a través de conexiones, se debe crear una tabla real, en lugar de una tabla temporal Global. No obstante, SQL Server ofrece esto como una opción.

     


     Norman M. Pardell 

    ||Microsoft Certified IT Professional|| Database Administrator. Database Developer. SQL Server 2008

    • Marcado como respuesta suhi_22 martes, 26 de abril de 2011 15:43
    domingo, 24 de abril de 2011 14:24