Últimas noticias
Loading...

Últimos artículos

Mostrando entradas con la etiqueta sql. Mostrar todas las entradas
Mostrando entradas con la etiqueta sql. Mostrar todas las entradas
jueves, 1 de mayo de 2008
SQL Server: Metadatos (III) - Aplicación práctica - Buscar una palabra en BBDD

SQL Server: Metadatos (III) - Aplicación práctica - Buscar una palabra en BBDD

Siguiendo la línea de los últimos artículos acerca de la utilidad práctica de los metadatos del SQL Server, vamos a crear un script para buscar una cadena de texto en nuestra base de datos. Con unas pocas modificaciones, nos serviría también para buscar números u otro tipo de datos que admita el SQL Server.

Para buscar la cadena en nuestra base de datos, vamos a seguir los siguientes pasos:
  1. Recorrer las tablas de la base de datos. Para cada tabla:
    1. Crear consulta de búsqueda sql = "Select count(*) From " + NOM_TABLA + " Where 1=0"
    2. Recorrer los campos de la tabla actual. Para cada campo del tipo "char", "varchar" o "nvarchar":
      1. Agregar una condición de búsqueda a la cadena SQL (concatenada con OR):
        1. sql = sql + ' OR ' + NOM_COLUMNA + ' like ''%' + CADENA_BUSCAR + '%'''
      2. Continuar con el siguiente campo.
    3. Ejecutar la sentencia sql resultante de recorrer los campos de la tabla.
      1. Si el resultado de la ejecución (count(*)) es mayor que cero, se ha encontrado el valor buscado.
    4. Continuar con la siguiente tabla.
Se puede observar que en la SQL que vamos a crear, se añade como condición WHERE la sentencia 1=0. Esto se hace porque se puede dar el caso que una tabla no tenga campos de texto, en ese caso, la única condición sería 1=0 que no se cumple nunca, y que no nos devolvería ningún registro (count = 0).
En caso que la tabla contenga algún campo de tipo texto, se añadiría a la condición WHERE con el operador OR, y si se cumple que el campo contiene la cadena a buscar, el resultado de la condición WHERE sería true, con lo que el count(*) devolvería uno o más registros. Por ej.:

Select count(*) From Usuarios Where 1=0 OR Nombre like '%Pablo%'.

En este caso, el texto coloreado en verde es añadido por el script como un literal, mientras que el texto rojo se añade en función de los campos que tiene cada tabla. Si la condición marcada en rojo se cumple, toda la condición WHERE será verdadera.



Como siempre, debemos incluir al inicio del script, la instrucción Use, con tal de seleccionar la BBDD en la que queremos trabajar:
Use [miBaseDeDatos]
1. Recorrer las tablas de la Base de datos.


Para recorrer las tablas de nuestra base de datos, vamos a hacer uso de la información de Metadatos contenida en information_schema.tables. Podemos añadir una condición WHERE para filtrar las tablas en las que queremos buscar.


DECLARE CURSOR_SELECT
CURSOR FOR
SELECT TABLE_NAME
FROM information_schema.tables
OPEN CURSOR_SELECT FETCH NEXT FROM CURSOR_SELECT INTO @NOM_TABLA
-- Recorre las tablas de la base de datos
WHILE @@FETCH_STATUS = 0
BEGIN
/* Realiza las operaciones necesarias */
FETCH NEXT FROM CURSOR_SELECT INTO @NOM_TABLA
END
/* Libera la memoria */
CLOSE CURSOR_SELECT
DEALLOCATE CURSOR_SELECT
1.1. Crear consulta de búsqueda.

Por cada tabla, vamos a crear una consulta SQL que servirá para localizar la palabra que estamos buscando dentro de la tabla actual. Para ello constuiremos una cadena que se compone de una parte fija #Select count(*) From NOM_TABLA Where 1=0 # y a la que añadiremos los distintos campos de la base de datos.
print '-----------------------'
print 'TABLA: ' + @NOM_TABLA
print '-----------------------'
-- Crea la cadena de búsqueda
SET @PROXIMA_SENTENCIA = 'SELECT Count(*) FROM ' + @NOM_TABLA + ' WHERE 1=0'

Además aprovechamos para imprimir por consola el nombre de la tabla.

1.2. Recorrer los campos de la tabla actual.

Para recorrer los campos de una tabla, vamos a hacer uso de la información contenida en information_schema.columns. Por simplificar, vamos a limitar la búsqueda a campos de tipo texto (nvarchar, varchar y char).
En cada iteración, se añade una condición de búsqueda del tipo " OR Nombre_Columna like '%Cadena a buscar%' ".

-- Crea el cursor de campos de búsqueda
DECLARE CURSOR_CAMPOS
CURSOR FOR
SELECT COLUMN_NAME
FROM information_schema.columns
WHERE TABLE_NAME like @NOM_TABLA
AND (DATA_TYPE = 'nvarchar' OR DATA_TYPE = 'varchar' OR DATA_TYPE = 'char')
OPEN CURSOR_CAMPOS FETCH NEXT FROM CURSOR_CAMPOS INTO @NOM_COLUMNA
WHILE @@FETCH_STATUS = 0
BEGIN
SET @PROXIMA_SENTENCIA = @PROXIMA_SENTENCIA + ' OR ' + @NOM_COLUMNA + ' like ''%' + @CADENA_BUSCAR + '%'''
FETCH NEXT FROM CURSOR_CAMPOS INTO @NOM_COLUMNA
END
-- Libera memoria
CLOSE CURSOR_CAMPOS
DEALLOCATE CURSOR_CAMPOS


1.3. Ejecutar sentencia.

El siguiente paso, será ejecutar la sentencia que se ha construido para la tabla actual. Se imprimirá el resultado de registros obtenidos, si el resultado es mayor de cero, se habrá encontrado la palabra buscada.

-- Ejecuta la sentencia para comprobar si obtiene algún resultado
SELECT @sql = 'DECLARE CURSOR_SENTENCIA CURSOR FOR ' + @PROXIMA_SENTENCIA
EXEC sp_executesql @sql
OPEN CURSOR_SENTENCIA FETCH NEXT FROM CURSOR_SENTENCIA INTO @REGISTROS
WHILE @@FETCH_STATUS = 0
BEGIN
print 'Registros ' + str(@REGISTROS)
FETCH NEXT FROM CURSOR_SENTENCIA INTO @REGISTROS
END
-- Libera memoria
CLOSE CURSOR_SENTENCIA
DEALLOCATE CURSOR_SENTENCIA


1.4. Continuar con la siguiente tabla.

Continuará con la siguiente tabla, repitiendo los pasos 1.1., 1.2. y 1.3.


Este ejemplo puede completarse con otros tipos de datos, seleccionando la manera adecuada para compararlos con el tipo de datos buscado.

Espero que os sea de utilidad!!

Código completo:


Use [miBaseDeDatos]

DECLARE @SQL NVARCHAR(4000)
DECLARE @PROXIMA_SENTENCIA NVARCHAR(3500)
DECLARE @NOM_TABLA NVARCHAR(255)
DECLARE @NOM_COLUMNA NVARCHAR(255)
DECLARE @REGISTROS int
DECLARE @CADENA_BUSCAR NVARCHAR(255)
SET @CADENA_BUSCAR = 'prueba'

DECLARE CURSOR_SELECT
CURSOR FOR
SELECT TABLE_NAME
FROM information_schema.tables

OPEN CURSOR_SELECT FETCH NEXT FROM CURSOR_SELECT INTO @NOM_TABLA
-- Recorre las tablas de la base de datos
WHILE @@FETCH_STATUS = 0
BEGIN
print '-----------------------'
print 'TABLA: ' + @NOM_TABLA
print '-----------------------'
-- Crea la cadena de búsqueda
SET @PROXIMA_SENTENCIA = 'SELECT Count(*) FROM ' + @NOM_TABLA + ' WHERE 1=0'
-- Crea el cursor de campos de búsqueda
DECLARE CURSOR_CAMPOS
CURSOR FOR
SELECT COLUMN_NAME
FROM information_schema.columns
WHERE TABLE_NAME like @NOM_TABLA
AND (DATA_TYPE = 'nvarchar' OR DATA_TYPE = 'varchar' OR DATA_TYPE = 'char')
OPEN CURSOR_CAMPOS FETCH NEXT FROM CURSOR_CAMPOS INTO @NOM_COLUMNA
WHILE @@FETCH_STATUS = 0
BEGIN
SET @PROXIMA_SENTENCIA = @PROXIMA_SENTENCIA + ' OR ' + @NOM_COLUMNA + ' like ''%' + @CADENA_BUSCAR + '%'''
FETCH NEXT FROM CURSOR_CAMPOS INTO @NOM_COLUMNA
END
-- Libera memoria
CLOSE CURSOR_CAMPOS
DEALLOCATE CURSOR_CAMPOS
print @PROXIMA_SENTENCIA
-- Ejecuta la sentencia para comprobar si obtiene algún resultado
SELECT @sql = 'DECLARE CURSOR_SENTENCIA CURSOR FOR ' + @PROXIMA_SENTENCIA
EXEC sp_executesql @sql
OPEN CURSOR_SENTENCIA FETCH NEXT FROM CURSOR_SENTENCIA INTO @REGISTROS
WHILE @@FETCH_STATUS = 0
BEGIN
print 'Registros ' + str(@REGISTROS)
FETCH NEXT FROM CURSOR_SENTENCIA INTO @REGISTROS
END
-- Libera memoria
CLOSE CURSOR_SENTENCIA
DEALLOCATE CURSOR_SENTENCIA
FETCH NEXT FROM CURSOR_SELECT INTO @NOM_TABLA
END

/* Libera la memoria */
CLOSE CURSOR_SELECT
DEALLOCATE CURSOR_SELECT
miércoles, 2 de abril de 2008
SQL Server: Metadatos (II) - Aplicación práctica - Vaciar base de datos

SQL Server: Metadatos (II) - Aplicación práctica - Vaciar base de datos

Continuando con el artículo en el que hablaba de la utilidad de los Metadatos para obtener información de nuestra base de datos, vamos a escribir un procedimiento almacenado cuya finalidad será la de vaciar todo el contenido (datos) de nuestra base de datos.

Este procedimiento resultará muy útil en aquellas bases de datos que contengan multitud de tablas relacionadas entre si. En estos casos, nos vemos obligados a ir eliminando los datos tabla a tabla, respetando las reglas de integridad, lo cual se convierte en una tarea muy complicada. Para automatizar este proceso seguiremos los siguientes pasos:

  1. Deshabilitar las restricciones de cada tabla de la base de datos.
  2. Vaciar los registros de las distintas tablas de la base de datos.
  3. Volver a habilitar las restricciones definidas en las tablas de la base de datos.
Y por supuesto, realizar una copia de seguridad de nuestra base de datos antes de ejecutar el script, por si algo fuese mal. Además como medida de seguridad adicional, podemos incluir al inicio del script, la instrucción Use, con tal de seleccionar la BBDD en la que queremos trabajar:

Use [miBaseDeDatos]

1. Deshabilitar restricciones de las tablas de la BBDD.

Para ello vamos a recorrer todas las restricciones de nuestra base de datos con la ayuda de la información contenida en information_schema.table_constraints. Además vamos a aprovechar para deshabilitar cada restricción a medida que vamos recorriendo el cursor.

DECLARE CURSOR_ALTER
CURSOR FOR
SELECT 'ALTER TABLE ' + TABLE_NAME + ' NOCHECK CONSTRAINT ' + CONSTRAINT_NAME, TABLE_NAME, CONSTRAINT_NAME
FROM information_schema.table_constraints
ORDER BY TABLE_NAME, CONSTRAINT_NAME
OPEN CURSOR_ALTER FETCH NEXT FROM CURSOR_ALTER INTO @PROXIMA_SENTENCIA, @NOM_TABLA, @NOM_CONSTRAINT
WHILE @@FETCH_STATUS = 0
BEGIN
exec (@PROXIMA_SENTENCIA)
FETCH NEXT FROM CURSOR_ALTER INTO @PROXIMA_SENTENCIA , @NOM_TABLA, @NOM_CONSTRAINT
END
/* Libera la memoria */
CLOSE CURSOR_ALTER
DEALLOCATE CURSOR_ALTER

07/05/2013 Actualización

En las nuevas versiones de SQL Server (yo lo he probado en SQL Server 2012), se puede ejecutar el siguiente script para realizar la misma tarea:


-- Deshabilitar
EXEC sp_msforeachtable "ALTER TABLE ? NOCHECK CONSTRAINT all"
 
-- Habilitar
exec sp_msforeachtable @command1="print '?'", @command2="ALTER TABLE ? WITH CHECK CHECK CONSTRAINT all"


2. Vaciar los registros de las distintas tablas de la base de datos.

De igual forma que en el paso anterior, vamos a recorrer todas las tablas de nuestra base de datos y eliminar sus registros. Para ello, utilizaremos la información que nos brinda information_schema.tables. Es muy importante que limitemos de alguna forma las tablas que se van a vaciar, por ejemplo, si las tablas de nuestra aplicación empiezan por TBL_ podríamos especificar en la condición WHERE que filtre por aquellas tablas que empiezan con este nombre. En el código que tenemos a continuación, se eliminarán los registros de todas las tablas excepto de sysdiagrams.

DECLARE CURSOR_DELETE
CURSOR FOR
SELECT 'DELETE FROM ' + TABLE_NAME, TABLE_NAME
FROM information_schema.tables
WHERE TABLE_NAME not like 'sysdiagrams'
ORDER BY TABLE_NAME
OPEN CURSOR_DELETE FETCH NEXT FROM CURSOR_DELETE INTO @SQL_DELETE, @NOM_TABLA
WHILE @@FETCH_STATUS = 0
BEGIN
exec (@SQL_DELETE)
FETCH NEXT FROM CURSOR_DELETE INTO @SQL_DELETE, @NOM_TABLA
END
/* Libera la memoria */
CLOSE CURSOR_DELETE
DEALLOCATE CURSOR_DELETE
3. Habilitar restricciones de las tablas de la BBDD.
Vamos a realizar el proceso inverso al seguido en el paso 1. De nuevo, haremos uso de la información contenida en information_schema.table_constraints. En este caso, utilizaremos la instrucción CHECK CONSTRAINT, que vuelve a activar la restricción.
DECLARE CURSOR_ALTER
CURSOR FOR
SELECT 'ALTER TABLE ' + TABLE_NAME + ' CHECK CONSTRAINT ' + CONSTRAINT_NAME, TABLE_NAME, CONSTRAINT_NAME
FROM information_schema.table_constraints
ORDER BY TABLE_NAME, CONSTRAINT_NAME
OPEN CURSOR_ALTER FETCH NEXT FROM CURSOR_ALTER INTO @PROXIMA_SENTENCIA, @NOM_TABLA, @NOM_CONSTRAINT
WHILE @@FETCH_STATUS = 0
BEGIN
exec (@PROXIMA_SENTENCIA)
FETCH NEXT FROM CURSOR_ALTER INTO @PROXIMA_SENTENCIA , @NOM_TABLA, @NOM_CONSTRAINT
END
/* Libera la memoria */
CLOSE CURSOR_ALTER
DEALLOCATE CURSOR_ALTER


Una vez ejecutados los tres pasos, habremos vaciado toda la información de nuestra base de datos. Como recomendación, se deberían limitar aquellas tablas de las que vamos a borrar los registros mediante la correspondiente instrucción dentro de la clausula WHERE (en el paso 2). También es interesante incluir comentarios y sentencias print que nos den una idea de la acción que esta realizando en cada momento el script, y de aquellas tablas que han sufrido cambios.
jueves, 12 de julio de 2007
SQL Server: Metadatos (I) - Procedimientos Almacenados

SQL Server: Metadatos (I) - Procedimientos Almacenados

Cuando una base de datos alcanza un tamaño significativo en lo relativo a procedimientos almacenados, se hace muy complicado tener una visión general de dichos procedimientos junto con los parámetros que aceptan. Es por ello que sería muy interesante obtener todos los procedimientos junto con sus parámetros y tipos de datos en una consulta SQL, con el fin de poder tratar esta información desde una aplicación externa, por ej. desde Excel o Access.
SQL Server nos brinda esta información en lo que se suele denominar metadata. Dentro del espacio INFORMATION_SCHEMA encontramos información relativa a los objetos de la base de datos. Para el caso que nos ocupa, utilizaremos la tabla PARAMETERS:

SELECT SPECIFIC_SCHEMA, SPECIFIC_NAME, PARAMETER_NAME, DATA_TYPE, PARAMETER_MODE
FROM INFORMATION_SCHEMA.PARAMETERS
WHERE
OBJECTPROPERTY ( OBJECT_ID ( QUOTENAME(SPECIFIC_SCHEMA) + '.' + QUOTENAME(SPECIFIC_NAME) ), 'IsMsShipped' ) = 0
Ejecutando la SQL en nuestra base de datos, obtendremos todos los procedimientos almacenados del sistema ordenados por la fecha de última modificación (descendente).

viernes, 25 de mayo de 2007
Regenerar identity en SQL Server

Regenerar identity en SQL Server

En ocasiones nos encontramos con una tabla que contiene datos y queremos vaciarla y volverla a rellenar por algún motivo. Si la tabla tiene una columna identity, al rellenarla de nuevo, empezará por el último identificador que tenía asignado. Para inicializar de nuevo la columna identity ejecutaremos la siguiente instrucción desde una consola de SQL:
 dbcc checkident (nombre_tabla, reseed , 0)

Quick Message
Press Esc to close
Copyright © 2013 Apaga y vámonos All Right Reserved