PostgreSQL: Consulta para saber en qué tabla está una columna

Lo hicimos en Oracle, en SQL-Server y en MySQL. No podíamos dejarnos PostgreSQL ¿cómo podemos saber en qué tabla está una columna sabiendo sólo el nombre de dicha columna?

Pues con una consulta sobre la vista columns, que contiene información sobre las columnas de todas las tablas y vistas. Veamos cómo sabríamos en qué tabla está la columna «NombrePaciente» (por poner un ejemplo práctico):

Select table_name
from columns
where column_name like 'NombrePaciente'

En vuestro caso cambiáis NombrePaciente por el nombre de columna que corresponda.

MySQL y MariaDB: Consulta para saber en qué tabla está una columna

El otro día lo vimos en SQL-Server, ayer en Oracle, vamos hoy con MySQL y su fork MariaDB, seguramente los gestores de bases de datos SQL libres más populares de la actualidad ¿Cómo puedo saber a qué tabla pertenece una columna sabiendo sólo el nombre de columna? Como en los casos anteriores, basta una consulta:

SELECT DISTINCT TABLE_NAME
    FROM INFORMATION_SCHEMA.COLUMNS
    WHERE COLUMN_NAME = 'Nombre_Columna'
        AND TABLE_SCHEMA='Nombre_BaseDatos';

Ya sabéis, os toca cambiar el nombre de columna y el nombre del esquema por los que correspondan en vuestro caso.

SQL-Server: Consulta para saber en qué tabla está una columna

Vamos con un tip rápido de SQL-Server, y seguramente útil en muchas ocasiones. Me acaba de pasar que ejecutaba un script para pasar datos de una base de datos vieja a una nueva (donde las tablas tienen algunas diferencias, al ser un versión posterior de la aplicación) y me devolvía como error que el tipo de datos no era válido para la columna Envases. Y me asalta la duda y la necesidad ¿en qué tabla está esa columna? Pues podemos saberlo con una consulta:

SELECT *
FROM INFORMATION_SCHEMA.COLUMNS
WHERE COLUMN_NAME = 'Envases'
ORDER BY DATA_TYPE

En vuestro caso debéis cambiar Envases por el nombre de columna que corresponda. Próximamente lo veremos en Oracle.

MySQL: Calcular una edad a partir de una fecha.

En fin, seguimos con el cálculo de edades a partir de fechas en diferentes SGBD. Ya hablamos de SQL-Server y de PostgreSQL, vamos ahora a ver cómo iría la cosa en MySQL/MariaDB.

Vamos a asumir que los datos están bien guardados, en una columna del tipo DATETIME. Como en el caso de Postgres, en MySQL dispones de una función que nos ayudará a hacer esto directamente, llamada TIMESTAMPDIFF(). Esta función recibe como argumentos la unidad de tiempo en la que queremos recibir la respuesta y las dos fechas entre las que queremos obtener la diferencia. Veamos el ejemplo para obtener la edad de alguien con esta función, sirviéndonos de una tabla de ejemplo llamada clientes que contendrá una columna FechaNac con la fecha de nacimiento de los mismos:

SELECT TIMESTAMPDIFF(YEAR,FechaNac,CURDATE()) AS edad
     FROM clientes;

PostgeSQL: Calcular una edad a partir de una fecha.

No hace mucho veíamos cómo calcular una edad en SQL-Server. Vamos ahora con otro SGBD ¿Cómo lo hago en Postgres? Pues con mucha menos dificultad, porque este gestor incluye ya una función integrada para el cálculo de edades, presente al menos desde la versión 9 (no se si antes) llamada age().

La función puede ser llamada con uno o con dos argumentos, siempre del tipo timestamp, y devuelve el interváluo entre ambos. Para el ejemplo imaginemos una tabla llamada clientes donde tenemos un campo FechaNac con la fecha de nacimiento guardada.

/*Con el primer ejemplo
pasando sólo una fecha
cogería la edad a día de hoy
de alguien nacido en esa fecha*/
Select age(timestamp FechaNac) from clientes

/*Con el segundo ejemplo
pasando dos fechas
cogería la edad que una
persona nacida en la fecha 2
tenía en la fecha 1*/

Select age(timestamp '2014-01-01',timestamp FechaNac) from clientes

SQL Server: Calcular una edad a partir de una fecha.

¿Cuántas veces no tenemos que sacar, en una consulta, la edad de una persona a partir de su fecha de nacimiento? Es una consulta que me toca hacer habitualmente (y que, mira por dónde, nunca había comentado aquí). ¿Cómo lo hacemos en SQL-Server?

Pensemos que tenemos una tabla clientes, donde hay un campo de tipo DATE llamado FechaNac en el que almacenamos sus fechas de nacimiento. Podrías creer que lo más simple es hacer lo siguiente:

Select DATEDIFF(YEAR,FechaNac,GETDATE()) as Edad from clientes

Pero hay un problema: Esa solución sólo resta los años, no tiene en cuenta el mes y el día ¿qué pasaría entonces? Que nos pondría la edad que ese cliente va a cumplir durante este año, no su edad real. ¿Cómo lo solucionamos? Hay muchas opciones, yo he optado por esta:

Select DATEDIFF(YEAR,FechaNac,GETDATE())
-(CASE
   WHEN DATEADD(YY,DATEDIFF(YEAR,clientes.FechaNac,GETDATE()),clientesFechaNac)>GETDATE() THEN 
      1
   ELSE 
      0 
   END) as Edad
 from clientes

Lo que hacemos es sumar la diferencia de años a la fecha de nacimiento y, en caso de que fuera posterior a hoy (es decir, todavía no ha cumpliado años) restamos 1 a la diferencia, si no restamos 0 y nos quedamos como estamos.

Otra opción, más elegante, podría ser esta:

Select floor(
(cast(convert(varchar(8),getdate(),112) as int)-
cast(convert(varchar(8),clientes.FechaNac,112) as int) ) / 10000
) as edad from clientes

En este caso convertimos la fecha al formato clásico de base de datos como una cadena que aglutina pegados Fecha, mes y día y lo convertimos a un entero (hoy nos quedaría por ejemplo 20151001), se lo restamos a la fecha de nacimiento, dividimos entre diez mil para obtener el año y redondeamos por defecto con la función floor().

Borrar un evento de MySQL

Hoy me preguntaba en la entrada sobre Eventos en MySQL cómo se borran, así que en vez de contestar en los comentarios voy a dejarlo por aquí en una minientrada general. ¿Cómo se borra un evento? Pues con Drop Event, cuya sintaxis es DROP EVENT [IF EXISTS] event_name. En el viejo ejemplo creábamos uno llamado e_ActualizaSaldoDiario, así que si quisiéramos borrarlo nos bastaría con hacer lo siguiente:

DROP EVENT e_ActualizaSaldoDiario

En caso de que el evento que intentamos borrar no existiera (por haberse borrado previamente) nos devolverá un error. Si queremos evitar esto podemos añadir IF EXISTS:

DROP EVENT IF EXISTS e_ActualizaSaldoDiario

Recordad que para borrarlos, igual que para crearlos, tenéis que tener permisos sobre los eventos en el schema.

SQL-Server ¿es mejor usar MAX() o TOP 1?

Una duda me asaltaba el otro día preparando una serie de consultas, en una de las cuales tenía que sacar la fecha más alta de una serie de registros. ¿Consumía menos recursos un MAX() o acaso era mejor recurrir a la conjunción de order by y Top 1?

Rebuscando por duckduckgo me encontré con este blog donde disipan la duda:

  1. Si el campo a buscar forma parte de un índice cluster, entonces da igual porque ambas se ejecutan a una velocidad extremadamente rápida
  2. Si el campo a buscar no es un índice cluster entonces MAX() da una respuesta más rápida porque la función está mejor optimizada y tiene menos carga que realizar un order by después del select

En el artículo original están los bancos de pruebas con resultados concretos.

Seguridad en WordPress ¿cómo cambiar el prefijo de la base de datos?

Si alguna vez has hecho una instalación de WordPress verás que te solicita, para crear el sitio, el nombre de una base de datos, el usuario con el que se conectará a ella, la contraseña de ese usuario y un prefijo. ¿Por qué un prefijo? Simplemente porque así puedes tener varias instalaciones de WordPress (o de otros CMS que usen nombres de tabla muy genéricos tipo «users», «posts», etc.) en una misma base de datos.

Si no cambiamos esta configuración por defecto el sistema pondrá el prefijo «wp_» a las tablas. El no poner un prefijo personalizado, en si, constituye un error. Porque dejando el prefijo por defecto estás provocando: a)Que si un atacante logra ver el nombre de una tabla descubra que el CMS que estás utilizando es WordPress y b) Que dicho atacante, entonces, pueda conocer los nombres de las tablas de tu base de datos. La solución es simple, durante la instalación define un prefijo personalizado.

¿Ya lo tienes instalado? Don’t worry, be nécora. No está todo perdido, tienes todavía varias opciones. La más rápida y simple, instalas este plugin que te permitará cambiarla cómodamente desde la interfaz gráfica. ¿La versión más larga y compleja y élite? Pues los siguientes pasos te lo explican:

Bueno, como paso previo, o paso 0 del proceso HAZ UN BACKUP DE TU BASE DE DATOS POR SI ALGO FALLA Y TIENES QUE RECUPERARLA. Consejo que debes tener siempre en mente cuando te pongas a tocar tablas de una instalación de cualquier cosa.

El primer paso: ir a wp-config.php y cambiar ahí el prefijo (en nuestro caso pondremos como prefijo personalizado my_b457Bch33s_ ).

$table_prefix  = 'my_b457Bch33s_';

El siguiente paso es renombrar todas las tablas de tu instalación de wordpress:

/*Básicamente vas haciendo esto con todas las tablas*/
RENAME table `wp_comments` TO `my_b457Bch33s_comments`;

Tras renombrar las tablas haces un update sobre la tabla options buscando todas las líneas que hagan referencia a tablas con el prefijo viejo para actualizarlas:

UPDATE `my_b457Bch33s_options` SET `option_name`=REPLACE(`option_name`,'wp_','my_b457Bch33s_') WHERE `option_name` LIKE '%wp_%';

Y con la tabla usermeta tres cuartos de lo mismo, update que te crió.

UPDATE `my_b457Bch33s_usermeta` SET `meta_key`=REPLACE(`meta_key`,'wp_','my_b457Bch33s_') WHERE `meta_key` LIKE '%wp_%';

Y tras esto deberías tener todo funcionando de nuevo, pero con el nuevo prefijo, más seguro contra potenciales atacantes.