Tag Archive: SQL


Después de mucho tiempo sin trabajar con mi servidor local de prueba, habia olvidado la contraseña del usuario root de la base de datos. Así que una googleada rápida he llegado a la siguiente solución:

Usted puede recuperar la contraseña del servidor de base de datos MySQL con los siguientes pasos:

Paso 1: Detener cualquier proceso del servidor MySQL.
Paso 2: Iniciar el proceso del servidor MySQL (mysqld) con la opción –skip-grant-tables por lo cual este no preguntará por la contraseña.
Paso 3: Conectar al servidor MySQL como el usuario root
Paso 4: Configurar una nueva contraseña para la nueva contraseña root
Paso 5: Salir y reiniciar el servidor MySQL

A continuación están los comandos necesarios para cada uno de los pasos mencionados anteriormente (iniciar sesión como el usuario root):

Paso # 1: Detener el servicio mysql

# /etc/init.d/mysql stop

Salida:

Stopping MySQL database server: mysqld.

Paso # 2: Iniciar el servidor MySQL sin contraseña:

# mysqld_safe --skip-grant-tables

Salida:

[1] 5988

Iniciando el motor de mysqld de las bases de datos desde /var/lib/mysql

mysqld_safe[6025]: started

Paso # 3: Conectar al servidor mysql usando el cliente mysql:

# mysql -u root

Salida:

Bienvenido al monitor de MySQL.  Comandos y con ; o \g.

Your MySQL connection id is 1 to server version: 5.0.21-log

Tipiar ‘help;’ o ‘\h’ para obtener ayuda. Tipiar ‘\c’ para en vaciar el buffer.

mysql>

Paso # 4: Configurar una nueva contraseña del servidor MySQL para el usuario root:

mysql> use mysql;
mysql> update user set password=PASSWORD("NEW-ROOT-PASSWORD") where User='root';
mysql> flush privileges;
mysql> quit

Paso # 5: Detener el servidor MySQL:

# /etc/init.d/mysql stop

Salida:

Stopping MySQL database server: mysqld

STOPPING server from pid file /var/run/mysqld/mysqld.pid

mysqld_safe[6121]: ended

[1]+  Done                    mysqld_safe –skip-grant-tables

Paso # 6: Iniciar el servidor MySQL y verificar la contraseña:

# /etc/init.d/mysql start
# mysql -u root -p

Fuente: http://www.codigomaestro.com/mysql/recuperar-contrasena-root-de-mysql/

Y aún estoy de exámenes, hasta el viernes, que estaré por fin libre de este gran peso, y esperemos, que con resultados satisfactorios.

Mientras tanto, para no tener abandonado el blog, ahi va mi pequeña aportación semanal.
Normalmente, en toda base de datos de una aplicación que se precie, suele tener algún campo del tipo Date. Pues Mysql, por norma general, si el campo no puede ser NULL, le asigna como valor por defecto ‘0000-00-00’, un valor que puede parecer inocente en un principio, pero si ya tenemos una aplicación Java funcionando o de una nueva, al intentar recuperarla del ResultSet, obtendremos una bonita excepción del tipo :


java.sql.SQLException: Value '0000-00-00' can not be represented as java.sql.Date

Aunque la primera solución que se nos puede pasar por la cabeza, después de las ganas de querer apalear la máquina virtual de Java, sería modificar la base de datos y cambiar todos los registros cuyo valor sea ‘0000-00-00’ por un NULL o si no podemos, por la fecha más antigua posible (Esa de 1970 que bla bla bla).  Ahora bién, esto puede ser bastante engorroso, aparte de que posiblemente nos pueda causar problemas posteriores con otras zonas de la aplicación. Pero por suerte, tenemos una solución bastante más asequible, rápida y escalable. Es tan sencillo, como pasarle como parámentro al conector de Mysql para java lo siguiente : “zeroDateTimeBehavior=convertToNull”, quedando por ejemplo, la línea de la conexión algo así:

"jdbc:mysql://localhost:3306/pagos?user=root&password=root&zeroDateTimeBehavior=convertToNull";

De esta forma, automaticamente, el conector, cada vez que recupere un registro del tipo fecha que sea cero, lo que hará será darle al ResultSet un null, solucionando así gran parte de nuestros problemas.

Si quereis aprender más sobre toda la funcionalidad del conector de Mysql, siempre podeis dirigiros a la documentación oficial del conector.

Cuando estamos tratando con consultas a bases de datos en Java, sobre todo en un proyecto Enterprise, podemos llegar a hablar de consultas kilométricas que acceden a varias tablas con una cantidad ingente de campos. Y si pretendemos hacer las cosas bien, utilizando los PreparedStatement, por temas de seguridad , legibilidad y reutilización, seguramente, si tenemos que hacer algún cambio en una sentencia, añadiendo o eliminando algún parametro, nos podemos encontrar con que deberemos cambiar bastantes líneas de código, en vez de la que debemos añadir/quitar solamente.

Vamos a poner un ejemplo práctico, si tenemos la siguiente sentencia de consulta a una base de datos:


SELECT usuarios.*, roles.descripcion, posts.entrada, posts.titulo FROM usuarios,descripcion,posts
WHERE usuarios.rolId=roles.id AND posts.userId=usuarios.id AND posts.fecha BETWEEN ? AND ?
AND usuarios.userId = ? AND posts.id = ? AND posts.isVisible = ? AND posts.visitas > ?

Esta consulta no es muy extensa, pero nos valdrá para ilustrar el supuesto práctico.  Ahora tendríamos el siguiente código Java para realizar la consulta:


String consulta = //la consulta de arriba;
PreparedStatement stmt = conexion.prepareStatement(consulta);
stmt.setDate(1,desde);
stmt.setDate(2,hasta);
stmt.setInt(3,userId);
stmt.setInt(4,postId);
stmt.setBoolean(5,isVisible);
stmt.setInt(6,numVisitas);

ResultSet result = stmt.executeQuery();

Esta sería la forma normal de trabajar, pero si en un futuro tenemos que realizar alguna modificación a la consulta,
por ejemplo, quitamos la necesidad de las dos fechas en la condición. Nos encontramos conque deberemos eliminar dos lineas de código
y modificar las otras 4, para que cuadre el número del parámetro. Esto no nos llevaría mucho tiempo en una sola consulta, pero si hubiera que modificar más consultas (porque se haya eliminado un campo que se utilizaba en todas las consultas como condición),  o si tratamos de una consulta con 20 parámetros por ejemplo, ya requeriría más tiempo empleado en el mantenimiento.

Así, que para ahorrar en tiempo de mantenimiento futuro, lo que podemos hacer, es insertar una variable que vaya aumentando con cada inserción de un nuevo parámetro, de esta forma,  no  tenemos que estar trabajando con el número de parámetro que se le pasa a los métodos set… y nos ahorraremos más de un dolor de cabeza. El código resultante, sería algo así:

int parameter=1;
String consulta = //la consulta de arriba;
PreparedStatement stmt = conexion.prepareStatement(consulta);
stmt.setDate(parameter++,desde);
stmt.setDate(parameter++,hasta);
stmt.setInt(parameter++,userId);
stmt.setInt(parameter++,postId);
stmt.setBoolean(parameter++,isVisible);
stmt.setInt(parameter++,numVisitas);

ResultSet result = stmt.executeQuery();

De esta forma, ya nos podemos despreocupar, de que el número de un parámetro coincida
con el de la consulta, y si hacemos alguna modificación en la consulta, no tendremos que realizar demasiado
cambio en el código y por último, nos facilita el copy & paste que tanto gusta a algunos.
Para finalizar, solo hay que recordar que el número de parametros, empieza con 1, no con 0 como los arrays, y que el número
de parametros que requiere la consulta, debe ser igual al número de parámetros que le pasamos, uno más o uno menos
resultará en una excepción.