Meter datos
INSERT es de lo más portátil que hay: se escribe igual en los
tres motores. Se nombran las columnas y se dan los valores en el mismo orden.
-- Una fila
INSERT INTO clientes (nombre, email, ciudad, saldo)
VALUES ('Julia Gomez', 'julia@correo.com', 'Bogota', 150000);
-- Varias de golpe, que es mucho mas rapido que una a una
INSERT INTO clientes (nombre, email, ciudad, saldo) VALUES
('Carlos Ruiz', 'carlos@correo.com', 'Medellin', 0),
('Ana Martinez', 'ana@correo.com', 'Bogota', 85000),
('Luis Herrera', NULL, 'Cali', -20000);No hemos puesto el id ni creado_en: los rellena la
base de datos, porque así se declararon en la lección 3. Y fíjate en el
NULL del correo de Luis: la columna admitía vacío, así que entra.
Recuperar el id que se acaba de crear
Este es el problema práctico: acabas de insertar un cliente y necesitas su
id para insertar su primer pedido. La base de datos lo generó, pero
tú no lo sabes.
Y aquí cada motor lo resuelve de una forma distinta. Es la
diferencia que más código rompe al portarlo, precisamente porque el
INSERT de arriba sí era idéntico.
INSERT INTO clientes (nombre, email, ciudad)
VALUES ('Marta Diaz', 'marta@correo.com', 'Bogota')
RETURNING id;id ---- 5
-- MySQL
INSERT INTO clientes (nombre, email, ciudad)
VALUES ('Marta Diaz', 'marta@correo.com', 'Bogota');
SELECT LAST_INSERT_ID();
-- SQL Server
INSERT INTO clientes (nombre, email, ciudad)
VALUES ('Marta Diaz', 'marta@correo.com', 'Bogota');
SELECT SCOPE_IDENTITY();En SQL Server se usa SCOPE_IDENTITY() y no
@@IDENTITY, aunque las dos parezcan hacer lo mismo.
@@IDENTITY devuelve el último id generado en la sesión,
incluido el que haya creado un disparador de otra tabla por debajo. Si esa tabla tiene
uno, te llevas un id que no es el tuyo, y el fallo no da error:
simplemente asocias el pedido al cliente equivocado.
Consultar: SELECT
Es lo que más vas a escribir en tu vida. La estructura básica es siempre la misma: qué columnas quieres, de qué tabla, con qué condición.
-- Todo, para explorar
SELECT * FROM clientes;
-- Solo lo que necesitas: asi va en codigo de verdad
SELECT nombre, ciudad, saldo FROM clientes;
-- Con condicion
SELECT nombre, saldo FROM clientes WHERE ciudad = 'Bogota';
-- Varias condiciones
SELECT nombre, saldo
FROM clientes
WHERE ciudad = 'Bogota' AND saldo > 100000;
-- Renombrar una columna en el resultado
SELECT nombre AS cliente, saldo AS saldo_actual FROM clientes;SELECT * está perfecto para explorar, y no debería quedar en
código de producción: trae columnas que no usas, y el día que alguien añada una
columna nueva a la tabla, tu consulta empieza a devolver algo distinto sin que nadie
haya tocado el programa.
Buscar dentro de un texto: LIKE
LIKE busca por coincidencia parcial usando dos comodines:
% es «cualquier cosa» y _ es «un carácter cualquiera».
-- Que empiece por
SELECT nombre FROM clientes WHERE nombre LIKE 'Ju%';
-- Que contenga
SELECT nombre FROM clientes WHERE nombre LIKE '%Gomez%';
-- Que termine en
SELECT email FROM clientes WHERE email LIKE '%@correo.com';La trampa silenciosa de esta lección: con la configuración
habitual, en MySQL y SQL Server LIKE NO distingue mayúsculas
-buscar gomez encuentra Gomez-, y en PostgreSQL SÍ las
distingue: gomez no encuentra Gomez.
La misma consulta devuelve resultados distintos según el motor, y
ninguno da error. En PostgreSQL existe ILIKE, que ignora
mayúsculas; la forma que funciona en los tres es comparar en minúsculas:
WHERE LOWER(nombre) LIKE LOWER('%gomez%').
Los operadores de filtro
Además de la comparación normal, hay cuatro formas de filtrar que evitan escribir condiciones larguísimas.
-- Uno de estos valores
SELECT nombre FROM clientes WHERE ciudad IN ('Bogota', 'Medellin', 'Cali');
-- En un rango, extremos incluidos
SELECT nombre, saldo FROM clientes WHERE saldo BETWEEN 50000 AND 200000;
-- Lo contrario
SELECT nombre FROM clientes WHERE ciudad NOT IN ('Bogota');
-- Sin dato: OJO, se usa IS NULL, no = NULL
SELECT nombre FROM clientes WHERE email IS NULL;La causa número uno de «la consulta no devuelve nada y no entiendo
por qué»: escribir WHERE email = NULL.
NULL significa «no se sabe», así que preguntar si un valor desconocido es igual a
otro valor desconocido no da ni verdadero ni falso: no devuelve nada.
Y no produce ningún error, solo un resultado vacío. Se usa siempre
IS NULL e IS NOT NULL.
Situaciones que aparecen aquí
Un apóstrofo rompe la consulta
Insertar O'Brien falla porque el apóstrofo cierra el
texto. Se escapa duplicándolo: 'O''Brien'.
Y esto conecta con algo mayor: cuando el dato viene de un formulario, nunca se pega dentro de la consulta. Se usan consultas parametrizadas, o alguien puede hacer que su «nombre» sea SQL. Es la inyección SQL.
Necesito buscar sin importar mayúsculas ni tildes
Para las mayúsculas, LOWER() en los dos lados funciona
en los tres motores.
Las tildes dependen de la intercalación configurada, y cada motor la maneja distinto. Si tus datos llevan tildes, hay que probarlo: no se puede asumir.
La consulta devuelve filas repetidas
SELECT DISTINCT ciudad FROM clientes; devuelve cada
valor una sola vez.
Es lo que se usa para responder «¿en qué ciudades tenemos clientes?».
Comillas simples o dobles
Las simples son para textos:
'Bogota'. Las dobles, en el estándar, son para nombres de
tablas y columnas.
MySQL es más permisivo y acepta las dobles para texto, y eso enseña una costumbre que se rompe al cambiar de motor. Usa siempre simples para texto.
Compruébalo tú mismo
Escribes WHERE email = NULL y no devuelve nada, aunque sabes que hay clientes sin correo. ¿Por qué?
La misma consulta con LIKE '%gomez%' encuentra resultados en MySQL y ninguno en PostgreSQL. ¿Qué pasa?
LOWER().Insertas un cliente y necesitas su id para crear su pedido. ¿Cómo lo obtienes en PostgreSQL?
Lo que sigue
Ya metes y sacas datos. En la siguiente lección los ordenas y los paginas -y ahí SQL Server se separa claramente de los otros dos- y aprendes a modificar y borrar sin provocar un desastre.
Siguiente: Ordenar, limitar, actualizar y borrar
Continuar ← Tablas, tipos y el id automático