Últimas noticias
Loading...

Últimos artículos

lunes, 22 de septiembre de 2008
Algunos comandos útiles en Microsoft Windows

Algunos comandos útiles en Microsoft Windows

En ocasiones hay algunas aplicaciones de Windows que por un motivo u otro desaparecen y resulta complicado encontrarlas.

Para acceder a estas herramientas, se pueden ejecutar los siguientes comandos (Inicio - Ejecutar...):
  • Herramienta de restauración del sistema: %systemroot%\system32\restore\rstrui.exe
  • Hotplug (desconexión de dispositivos externos, usb...): %systemroot%\system32\Rundll32.exe shell32.dll,Control_RunDLL hotplug.dll
  • Microsoft Word: winword
  • Microsoft Excel: excel
  • Escritorio Remoto: mstsc

martes, 1 de julio de 2008
Importar certificados en Java

Importar certificados en Java

Cuando desarrollamos una aplicación en Java que va ha hacer uso de un recurso seguro (mediante un certificado), debemos asegurarnos que este certificado podrá ser validado por una entidad certificadora que reconozca Java. Debido a que Java es un lenguaje multi-plataforma, no utiliza la información de certificados alojada en el Sistema Operativo.







Por defecto, la máquina virtual de Java dispone de las Entidades Certificadoras (CA) más comunes, como Verisign o Thawte. Sin embargo, suele darse el caso, sobretodo en entornos de desarrollo, que necesitemos utilizar una Entidad Certificadora "de prueba". En este caso, debemos importar esta CA en el almacén de claves de la máquina virtual que estemos utilizando.


Importar Certificado en el almacén de certificados (keystore)


La máquina virtual de Java (JVM) cuenta con un almacén de claves (keystore) que incorpora las entidades más habituales y la posibilidad de agregar aquellas que nos sean necesarias. El keystore se encuentra en la ruta: JVM_PATH\lib\security\cacerts. Por ejemplo:


C:\Archivos de programa\Java\jre1.6.0_05\lib\security\cacerts
C:\Archivos de programa\Java\jdk1.5.0_15\jre\lib\security


Para añadir una nueva entidad certificadora a la JVM que estemos utilizando, debemos utilizar el comando keytool (JVM_PATH\bin\keytool):



keytool -import -keystore "C:\Archivos de
programa\Java\jre1.6.0_05\lib\security\cacerts" -file
c:\NuevaEntidadCertificadora.cer -alias CA_SwitchOffAndLetsGo -storepass
changeit



Puede observarse que el almacén de certificados contiene la contraseña por defecto 'changeit'. El nombre que especifiquemos en el alias, debe ser único en el keystore y servirá de referencia futura en el almacén. Podemos listar los certificados instalados utilizando la opción list del keytool:



keytool -list -keystore "C:\Archivos de
programa\Java\jre1.6.0_05\lib\security\cacerts" -storepass changeit



Importar Certificado utilizando el panel de control de Java (Windows)


Atención: con esta opción únicamente se añadirán los certificados a la instalación activa de la JVM en Windows.


Para añadir la nueva entidad, se accederá al Panel de Control de Windows, y se seleccionará la opción "Java". Seguidamente se marcará la pestaña "Seguridad" y se pulsará sobre el botón "Certificados".


En el apartado de Certificados, se seleccionará la opción "Importar" y se localizará el archivo que contiene el certificado (si el certificado tiene extensión .cer se tendrá que seleccionar la opción 'Todos los archivos'). El nuevo certificado aparecerá en la pestaña "Usuario".

martes, 10 de junio de 2008
Modificar un mensaje SOAP desde Java

Modificar un mensaje SOAP desde Java

El propósito del siguiente artículo, es explicar el modo en que se puede modificar un mensaje SOAP en una llamada a un Web Service desde NetBeans. Esto es muy útil en aquellos casos en que consumimos un WebService generado en otro lenguaje de programación, y no encontramos la forma de acceder a algún objeto que se encuentra dentro del mensaje.

Imaginemos que tenemos el siguiente mensaje SOAP para la llamada a un WebService:

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
<cabeceraSOAP xmlns="http://switchoffandletsgo.blogspot.com/">
<ipOrigen>string</ipOrigen>
</cabeceraSOAP>
</soap:Header>
<soap:Body>
<SumaNumeros xmlns="http://switchoffandletsgo.blogspot.com/">
<intNum1>int</intNum1>
<intNum2>int</intNum2>
</SumaNumeros >
</soap:Body>
</soap:Envelope>

Se puede observar que el WebService tiene un método SumaNumeros que recibe dos enteros y devolvería la suma de ambos. Además contiene una cabecera SOAP en la que se debe enviar la dirección IP de origen.

Al generar las clases necesarias para realizar la llamada utilizando el WSDL del WebService, NetBeans no es capaz de reconocer la cabecera del mensaje SOAP, con lo que no podemos establecer directamente la variable cabeceraSOAP. Por lo tanto, tendremos que agregar un Handler que intervenga antes de realizar la llamada, y añada al mensaje la cabecera que necesitemos.

Para ello creamos una nueva clase, por ejemplo SumaNumerosHandler y pedimos que implemente la clase SOAPHandler<SOAPMessageContext>:


public class SumaNumerosHandler implements SOAPHandler<SOAPMessageContext> {

}

Después le pedimos a NetBeans que realice los imports necesarios y que implemente los métodos abstractos, con lo que nos aparecerá la definición de los métodos que tenemos que implementar:


public Set<QName> getHeaders() {
throw new UnsupportedOperationException("Not supported yet.");
}


public boolean handleMessage(SOAPMessageContext arg0) {
throw new UnsupportedOperationException("Not supported yet.");
}


public boolean handleFault(SOAPMessageContext arg0) {
throw new UnsupportedOperationException("Not supported yet.");
}


public void close(MessageContext arg0) {
throw new UnsupportedOperationException("Not supported yet.");
}

En concreto vamos a centrarnos en el método handleMessage, que se ocupará de capturar la salida o entrada del mensaje SOAP. Para el resto de métodos que no nos ocupan, vamos a definir una serie de valores de retorno por defecto:


public Set<QName> getHeaders() {
return Collections.EMPTY_SET;
}


public boolean handleFault(SOAPMessageContext messageContext) {
return true;
}


public void close(MessageContext context) {
}

Método handleMessage

Como se puede observar, este método recibe un parámetro SOAPMessageContext. Esta interface da acceso al mensaje SOAP en cada petición o respuesta que se realiza en la comunicación, pudiendo modificar el contenido de este mensaje.

Para obtener el mensaje, llamamos al método getMessage():

SOAPMessage msg = messageContext.getMessage();

También necesitaremos conocer la dirección en la que viaja el mensaje, esto es, si se trata de un mensaje de salida o de entrada. En nuestro caso, necesitaremos modificar únicamente el mensaje de salida (petición). Podemos obtener esta información mediante el método get(), tal como se ilustra en el siguiente fragmento de código:

boolean bolMsgSalida= (Boolean) messageContext.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);

Por último, para añadir la cabecera a nuestro mensaje de salida, vamos a hacer uso de una serie de objetos que nos permitirán editar y modificar el mensaje SOAP:

// Obtenemos el contenedor del mensaje SOAP
SOAPPart sp = msg.getSOAPPart();

// A partir del contendor, obtenemos el nodo "Envelope"
SOAPEnvelope env = sp.getEnvelope();

// Instanciamos un objeto SOAPFactory para crear cualquier elemento perteneciente a un mensaje SOAP, en nuestro caso, los nodos que formarán la cabecera
SOAPFactory soapFactory = SOAPFactory.newInstance();

// Definimos los elementos a incluir en el mensaje
SOAPElement soapElementoCabecera = soapFactory.createElement("cabeceraSOAP","","http://switchoffandletsgo.blogspot.com/");

SOAPElement soapIpOrigen= soapFactory.createElement("ipOrigen","", "http://switchoffandletsgo.blogspot.com/");

// Rellenamos la información del nodo ipOrigen
soapIpOrigen.addTextNode("192.168.0.1");

// Incluimos los elementos dentro de los objetos correspondientes
soapElementoCabecera.addChildElement(soapIpOrigen);

SOAPHeader soapHeader = env.addHeader(); // Crea un elemento cabecera SOAP

soapHeader.addChildElement(soapElementoCabecera);

Si no se ha producido ninguna excepción, el método devolverá true.

Este manejador de mensajes SOAP, debería generar el siguiente nodo dentro del mensaje que se enviará al servidor:

<soap:Header>
<cabeceraSOAP xmlns="
http://switchoffandletsgo.blogspot.com/">
<ipOrigen>1921.168.0.1</ipOrigen>
</cabeceraSOAP>
</soap:Header>
Finalmente, debemos asignar el nuevo manejador al Web Service que queremos consumir. Para ello, accederemos a la carpeta "Web Service References" de nuestro proyecto de NetBeans, y pulsaremos con el botón derecho sobre el Web Service que queremos asignar. En el menú desplegable aparecerá la opción "Configure Handlers...".


Únicamente tendremos que añadir "Add..." nuestra clase SumaNumerosHandler y aceptar.

A partir de este ejemplo, las opciones son infinitas, podemos modificar cualquier parte del mensaje SOAP, entrante o saliente, según sean nuestras necesidades. En todo caso, siempre que sea posible, la mejor opción reside en utilizar las clases y métodos que genera NetBeans a partir del WSDL del Web Service.
martes, 6 de mayo de 2008
Wish List

Wish List

Siguiendo la línea del post en el que enumero los libros que he leído últimamente, he decidido crear una pequeña lista de aquellos libros que me gustaría leer.



Junot Díaz
La maravillosa vida breve de Oscar Wao (Premio Pulitzer 2008).
Las tribulaciones de un joven latino en Nueva Jersey. La esperada primera novela de Junot Díaz. La vida nunca ha sido fácil para Oscar Wao, un dominicano dulce, obeso y algo desastroso que vive con su madre y su hermana en un gueto de Nueva Jersey. Oscar sueña con convertirse en un J.R.R. Tolkien dominicano y, por encima de todo, con encontrar el amor de su vida. Pero puede que nunca alcance sus metas debido a una extraña maldición presente en su familia desde hace generaciones; enviando a los Wao a prisión, predisponiéndolos a accidentes trágicos y, ante todo, al desamor. Después del éxito internacional de Los Boys (Mondadori, 1996), Junot Díaz recrea, con humor, la experiencia de los dominicanos en Estados Unidos y la capacidad de perseverar en medio del desengaño amoroso y la pérdida.




José Saramago
Ensayo sobre la ceguera.La novela relata cómo una extraña epidemia de ceguera asola todo un país. Un pobre hombre que espera en su coche frente a un semáforo es el primero en padecerla y a partir de entonces se extiende cada vez más rápidamente entre la población. Los afectados son puestos en cuarentena, pero resulta imposible contener la enfermedad y las calles acaban llenándose de ciegos que son víctimas de este inexplicable mal consistente en una infinita ceguera blanca, como un mar de leche. A medida que aumenta el temor y la crisis en el país, gradualmente las personas se convierten en presa de los más bajos instintos del ser humano, llegando a los extremos más miserables.
El profundo egoísmo que marca a los distintos personajes en la lucha por la supervivencia, se convierte en una parábola de la sociedad actual, trascendiendo así el significado de ceguera más allá de la propia enfermedad física.
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.
martes, 22 de enero de 2008
Libros

Libros

No todo iba a ser programación... Aprovecho este blog para añadir algunos libros que he leído, así como una valoración (muy personal) del mismo. Que nadie piense que quiero hacer critica literaria, simplemente quiero reflejar si me ha gustado.
Juan Eslava Galán
En busca del Unicornio.
La novela, ambientada a fines del siglo XV, narra la historia de un personaje ficticio a quien se envía en busca del cuerno del unicornio, que se supone aumentará la virilidad del rey Enrique IV de Castilla, llamado el Impotente. En la trama argumental, habilísima y muy amena, dentro de una escrupulosa fidelidad a la ambientación histórica, se suceden las más curiosas e inesperadas peripecias, siempre con un fondo emotivo y poético que da fuerza y encanto mítico al relato. El autor ha logrado un estilo que es un maravilloso equilibrio entre la soltura y agilidad narrativa y el sabor arcaico que requería el tema. En suma, una deliciosa novela de aventuras en donde coexisten lo fantástico, lo humorístico y lo dramático.
10/10
Ken Follet
Los pilares de la Tierra.
El gran maestro de la narrativa y el suspense nos transporta a la Edad Media, a un fascinante mundo de reyes, damas, caballeros, pugnas feudales, castillos y ciudades amuralladas. El amor y la muerte se entrecruzan vibrantemente en este magistral tapiz cuyo centro es la construcción de una catedral gótica. La historia se inicia con el ahorcamiento público de un inocente y finaliza con la humillación de un rey. Los pilares de la tierra es la obra maestra de Ken Follett y constituye una excepcional evocación de una época de violentas pasiones.
10/10
Matilde Asensi
Iacobus.
Galcerán de Born; monje de una orden militar, es enviado por el papa Juan XXII a investirgar la misteriosa muerte de su antecesor Clemente V y la del rey Feliope IV de Francia, tras la ejecución del Gran Maestre de la Orden del Temple. a partir de aquí se inicia una vertiginosa aventura que nos conducirá de la sede papal de Aviñon a París y de allí, a lo largo del Camino de santiago, hasta el confín del mundo, Finisterre.
9/10
El último Catón.
Tras el éxito de El salón de ámbar e Iacobus, Matilde Asensi nos presenta una nueva novela tan impactante como aquellas. Todo comienza cuando una científica que trabaja para el Vaticano es llamada para descifrar las extrañas señales aparecidas en el cuerpo de un etíope fallecido en extrañas circunstancias. A partir de aquí se desplegará una trama trepidante y que pondrá al descubierto una siniestra conspiración para atentar contra las reliquias más sagradas de la Iglesia.
9/10
Todo bajo el cielo.
Elvira, una pintora española afincada en el París de las vanguardias, recibe la noticia de que su marido, con el que está casada por amistad, ha muerto en su casa de Shanghai en extrañas circunstancias.
Acompañada por su sobrina, zarpa desde Marsella en barco para recuperar el cadáver de Remy sin saber que éste es sólo el principio de una gran aventura por China en busca del tesoro del Primer Emperador. Sin tiempo para reaccionar se verá perseguida por los mafiosos de la Banda Verde y los eunucos imperiales, y contará con la ayuda del anticuario Lao Jiang y su sabiduría oriental en un gran recorrido que les llevará desde Shangai hasta Xián.
8/10
John Boyne
El niño con el pijama de rayas.
Aunque el uso habitual de un texto como éste es describir las características de la obra, por una vez nos tomaremos la libertad de hacer una excepción a la norma establecida. No sólo porque el libro que tienes en tus manos es muy difícil de definir, sino porque estamos convencidos de que explicar su contenido estropearía la experiencia de la lectura. Creemos que es importante empezar esta novela sin saber de qué trata.
No obstante, si decides embarcarte en la aventura, debes saber que acompañarás a Bruno, un niño de nueve años, cuando se muda con su familia a una casa junto a una cerca. Cercas como ésa existen en muchos sitios del mundo, sólo deseamos que no te encuentres nunca con una. Por último, cabe aclarar que este libro no es sólo para adultos; también lo pueden leer, y sería recomendable que lo hicieran, niños a partir de los trece años de edad.
7/10
Eduardo Mendoza
El asombroso viaje de Pomponio Flato
En el siglo I de nuestra era, Pomponio Flato viaja por los confines del Imperio romano en busca de unas aguas de efectos portentosos. El azar y la precariedad de su fortuna lo llevan a Nazaret, donde va a ser ejecutado el carpintero del pueblo, convicto del brutal asesinato de un rico ciudadano. Muy a su pesar, Pomponio se ve inmerso en la solución del crimen, contratado por el más extraordinario de los clientes: el hijo del carpintero, un niño candoroso y singular, convencido de la inocencia de su padre, hombre en apariencia pacífico y taciturno, que oculta, sin embargo, un gran secreto. Cruce de novela histórica, novela policíaca, hagiografía y parodia de todas ellas, 'El asombroso viaje de Pomponio Flato' es la obra más insólita e inesperada de Eduardo Mendoza, y también una de las más ferozmente divertidas. Como en el Quijote se ponían en solfa los libros de caballerías, aquí se ajustan las cuentas a muchas novelas de consumo, y se construye, al mismo tiempo, una nueva modalidad del género más característico de Eduardo Mendoza: la trama detectivesca original e irónica, que desemboca en una sátira literaria y en una desternillante creación de inagotable vitalidad novelesca.
8/10
HermanHesse Hermann Hesse
siddhartha1 Siddharta.
Novela de aprendizaje espiritual del hijo de un brahman. Se trata más de una novela de evolución interior que de una novela de acción. A través del encuentro con diferentes personajes, asistimos al desarrollo personal del protagonista hacia la pureza espiritual y la paz interior.
8/10
flann.obrien Flann O'Brien
lavidadura La vida dura. Una exégesis de lo escuálido.
A la casa del disputador señor Collopy arriban dos niños huérfanos. Mientras el señor Collopy se dedica a una misteriosa y humanitaria labor en favor de las mujeres, los chicos crecen entre los aromas del buen whisky y de la mala cocina. Manus, el hermano, pronto demuestra ser un maestro en los negocios. Con virtuoso y cruel ingenio, Flann O' Brien nos ofrece un argumento a escala clásica; su economía es incomparable, su inventiva desbordante.
6/10
Fuente comentarios:http://www.lecturalia.com/
Quick Message
Press Esc to close
Copyright © 2013 Apaga y vámonos All Right Reserved