Fran Otero

Programación C#, ASP.NET,SqlServer, Mobile y electrónica.

Puesta a cero de la base de datos en pre-producción

Tenemos nuestro nuevo proyecto preparado para el despliegue. Subimos nuestro sitio web al servidor de producción, ejecutamos el script de creación de la base de datos, configuramos la aplicación y vamos a probar y ..... no funciona grrrr#**&*!!!! ¡A cuántos nos sonará este tema! Lo cierto es que es posible ( e incluso probable) que con el cambio de entorno tengamos que hacer unos cuantos retoques en nuestra aplicación, realizar unas cuantas pruebas, etc. Despues de esto nuestra recién creada base de datos estará sucia y posiblemente queramos volver a inicializarla.

Por diversos motivos puede que no nos interese cargarnos la base de datos otra vez, con lo cual intentaremos unicamente borrar las tablas (puede que ni siquiera tengamos permisos para borrar la base y volverla a crear, de ahí el interes de este método). Podemos utilizar un procedimiento que recorra las tablas listadas en INFORMATION_SCHEMA.TABLES e vaya ejecutando un delete sobre ellas. Con este método únicamente borraremos parte de las tablas, ya que tenemos altas probabilidades de que muchas de las filas se queden bloqueadas por relaciones foreign key al ejecutar el barrido con un orden arbitrario (el de INFORMATION_SCHEMA.TABLES). Además tenemos el problema añadido de que los índices de las tablas no se reinicializan ya que debido otra vez a las foreign keys no podemos utilizar Truncate en lugar de Delete.

El código listado a continuación viene a solucinonar la problemática descrita, borrando todas las tablas de la base de datos independientemente de sus relaciones y reinicializando los índices a 0 en las tablas que dispongan de este tipo de campos. Nótese que el código hace incidencia especialmente en lo funcional, obviando consideraciones que nos distaigan del objetivo principal

            

            //Definimos la conexión a la base

            SqlConnection cn = new SqlConnection("ConnectionString");

            //Definimos un comando auxiliar

            SqlCommand aux = new SqlCommand("", cn);

            //Por último un comando auxiliar que carga las tablas de la base de datos.

            SqlCommand select = new SqlCommand(@"select * from INFORMATION_SCHEMA.TABLES where TABLE_TYPE like 'BASE TABLE'", cn);

            SqlDataAdapter selectDA = new SqlDataAdapter(select);

            DataTable tablas;

            selectDA.Fill(tablas = new DataTable());

            cn.Open();

            bool repetir;

            do

            {

                repetir=false;

                foreach (DataRow tabla in tablas.Rows)

                {//Borramos cada una de las tablas

                    aux.CommandText = "Delete " + tabla["TABLE_NAME"].ToString();

                    try

                    {

                        aux.ExecuteNonQuery();

                    }

                    catch (SqlException ex)

                    {

                                               if(ex.Number==547) //Infracción de FK: hay que repetir el borrado

                            repetir=true;

                    }

                }

            } while (repetir);

            foreach (DataRow tabla in tablas.Rows)

            {                   

                aux.CommandText = "DBCC CHECKIDENT (" + tabla["TABLE_NAME"] + ",RESEED,0)";

                try

                {

                    aux.ExecuteNonQuery();

                }

                catch

                {}//No todas las tablas tienen columnas de identidad para regenerar

            }

            cn.Close();

Posted: 7/2/2009 16:53 por Fran Otero Otero | con 3 comment(s)
Archivado en:
Comparte este post:

Comentarios

Fran Otero Otero ha opinado:

Por supuesto el truncate es mejor que la solución del artículo, pero al intentar ejecutarla sobre una tabla con claves foráneas devuelve una SqlException:

"Cannot truncate table 'nombreTabla' because it is being referenced by a FOREIGN KEY constraint."

¿Alguna idea para evitarlo?

Un saludo,

# February 8, 2009 9:42 PM

Guillermo ha opinado:

Lo que se puede hacer es alterar la tabla al inicio, para eliminar los constraints de FK y luego hacer el truncate.

# February 9, 2009 3:59 PM