Bloque III · Tema 3 · Cuerpo de Técnicos Auxiliares de Informática
Así lo numera la convocatoria: Bloque III. Desarrollo de sistemas. En nuestro temario es el tema 17 de 33.
Lenguajes de interrogación de bases de datos. Estándar ANSI SQL. Procedimientos almacenados. Eventos y disparadores.
El tema de SQL, y el que más código literal pone el tribunal en las opciones: 90 preguntas oficiales del INAP se responden con él. Va sentencia a sentencia — CREATE TABLE con sus restricciones, los cuatro JOIN, GROUP BY con su BY, subconsultas, TOP con su ORDER BY DESC — y con la sintaxis exacta de los procedimientos almacenados, los disparadores y los eventos, incluidas las cuatro formas falsas que el tribunal pone al lado de cada una. Con OQL, CQL, Cypher y XQuery cerrando el mapa de lenguajes de interrogación.
Tema desarrollado para el ejercicio único del Cuerpo de Técnicos Auxiliares de Informática de la Administración del Estado. Es el tema 3 del bloque III «Desarrollo de sistemas», que en nuestra numeración interna es el tema 17 de 33.
Cuánto pesa y cómo pregunta. El bloque III aporta 22 de las 80 preguntas de la primera parte y, además, es uno de los dos bloques de los que sale el supuesto práctico. Cruzando el enunciado de este tema con el corpus de exámenes del INAP aparecen 90 preguntas oficiales, y no por casualidad: casi todos los supuestos prácticos llevan dentro tres o cuatro sentencias SQL, y el tribunal las pone literales, con las cuatro opciones idénticas salvo una palabra, una coma o una cláusula.
Ahí está la clave de cómo hay que estudiarlo. Este tema no se aprueba entendiendo qué es una consulta: se aprueba habiendo escrito la sentencia. La diferencia entre acertar y fallar está en saber que el GROUP BY lleva BY, que el trigger se declara con ON y sin la palabra TABLE, que TOP(10) sin ORDER BY DESC no devuelve los diez últimos y que SUM(*) no existe. Por eso este apunte va con el código delante y, cuando el tribunal ya ha preguntado una sentencia, con las variantes falsas que puso al lado.
⚠️ Este tema se solapa a propósito con el tema 5 del bloque II, el de sistemas gestores. Allí se estudia qué es un gestor y cómo se modela; aquí se estudia cómo se le habla. Si algo de vocabulario suena repetido —los sublenguajes, las propiedades de las transacciones— es deliberado: son las dos preguntas del mismo asunto y el tribunal las hace por separado.
Índice
- Los lenguajes de interrogación
- El estándar ANSI SQL
- DDL: definir la base de datos
- DML y DQL: consultar y manipular
- INSERT, UPDATE, DELETE y MERGE
- SELECT: el orden que se escribe y el que se evalúa
- WHERE y sus operadores
- Combinaciones
- Agregación: GROUP BY y HAVING
- Subconsultas
- Operadores de conjuntos
- CASE, COALESCE y las funciones que caen
- Ordenar y quedarse con unas pocas filas
- Consultas con WITH y consultas recursivas
- Funciones de ventana
- DCL y TCL: permisos y transacciones
- Procedimientos almacenados
- Disparadores
- Eventos programados
- Los otros lenguajes de interrogación
- Cómo llega la consulta al gestor
- Cuadros para memorizar
- Lo que ya ha preguntado el tribunal
1. Los lenguajes de interrogación
Un lenguaje de interrogación o de consulta es el que permite pedirle datos a un sistema gestor sin escribir el programa que los recorre. Es, en el fondo, la promesa que justifica una base de datos frente a un fichero: en el fichero, cada consulta nueva exigía un programa nuevo; con un lenguaje de consulta, la consulta nueva se escribe en una línea y el gestor decide cómo resolverla.
1.1. Procedimental frente a declarativo
La distinción de partida se explica en una frase: en un lenguaje procedimental se dice cómo obtener el resultado, y en uno declarativo se dice qué resultado se quiere.
| Enfoque | Qué se escribe | Ejemplos |
|---|---|---|
| Procedimental | La secuencia de operaciones que hay que aplicar, en orden. | El álgebra relacional: selecciona, proyecta, combina. |
| Declarativo | La descripción del resultado, sin plan de ejecución. | El cálculo relacional y, sobre él, SQL. |
SQL se parece más al cálculo que al álgebra —se describe el resultado— pero conserva del álgebra sus operaciones y su vocabulario, y por eso las preguntas de examen saltan de un lenguaje al otro sin avisar. Los dos tienen la misma potencia expresiva, y a esa equivalencia se la llama completitud relacional: cualquier consulta que se pueda escribir en uno se puede escribir en el otro.
De ahí sale la pieza que hace todo esto posible: el optimizador. Como el programador no dice cómo, alguien tiene que decidirlo, y ese alguien estima el coste de cada plan alternativo a partir de las estadísticas del catálogo. Esa es la razón profunda de que dos consultas que devuelven lo mismo puedan tardar segundos o minutos, y de que actualizar las estadísticas sea una tarea rutinaria de administración.
1.2. El mapa completo: qué lenguaje pregunta a qué base de datos
El enunciado habla de «lenguajes» en plural, y el tribunal lo ha tomado al pie de la letra: ha preguntado por cinco distintos. Este cuadro es el mapa entero, y conviene tenerlo antes de bajar al detalle de cada uno.
| Lenguaje | Interroga a | Qué devuelve |
|---|---|---|
| SQL | Bases de datos relacionales y objeto-relacionales | Conjuntos de filas |
| OQL (Object Query Language) | Bases de datos orientadas a objetos, según ODMG 3.0 | Objetos, y se navega por referencias con la notación de punto |
| XQuery y XPath | Documentos y colecciones XML | Secuencias de nodos o de valores |
| CQL (Cassandra Query Language) | Apache Cassandra, de familias de columnas | Filas, con sintaxis deliberadamente parecida a la de SQL |
| Cypher | Neo4j, de grafos | Nodos, relaciones y caminos |
| SPARQL | Grafos RDF de la web semántica | Tripletas y tablas de resultados |
| MDX | Cubos multidimensionales OLAP | Celdas de un cubo |
| GraphQL | Una API, no una base de datos | El subconjunto exacto de campos que pide el cliente |
🚨 Dos de esta tabla han caído literalmente. La primera, en los dos modelos de 2026: «¿cuál de las siguientes bases de datos utiliza Cypher como lenguaje de consulta?», con MongoDB, CouchDB y Cassandra como distractores; la respuesta es Neo4j. La segunda, en los dos modelos de 2024: «¿qué es el lenguaje OQL en el contexto de las bases de datos orientadas a objetos?»; la respuesta que dio por buena el tribunal es un lenguaje de consulta de datos, y los distractores decían que era de definición, que era de manipulación y que no existía tal lenguaje.
⚠️ Cuidado con la última fila, porque induce a error: GraphQL no es un lenguaje de interrogación de bases de datos. Es un lenguaje para consultar una interfaz de programación, y detrás de él puede haber un gestor relacional, uno documental o ninguno. Que el nombre lleve las mismas cuatro letras que el de grafos no significa que tenga nada que ver con ellos.
1.3. Dónde se ejecuta la consulta
La consulta se escribe en el cliente y se ejecuta en el servidor, y entre los dos hay siempre una capa de conectividad. Conviene tenerlo presente desde el principio, porque explica varias decisiones del resto del tema:
- La aplicación no habla con el gestor: habla con un controlador —ODBC, JDBC, ADO.NET— que traduce al protocolo de red del fabricante.
- Cada sentencia que viaja obliga a un ida y vuelta. De ahí que un procedimiento almacenado que agrupa diez sentencias sea más rápido que diez sentencias sueltas: reduce el tráfico de red y el trabajo de análisis del gestor.
- La sentencia que llega al servidor se analiza, se optimiza y se ejecuta, y muchos gestores guardan el plan resultante para reutilizarlo. Esa es la razón de que las sentencias preparadas rindan mejor cuando la misma consulta se repite con distintos valores.
2. El estándar ANSI SQL
2.1. De SEQUEL a SQL:2023
SQL —Structured Query Language— nació en los laboratorios de IBM en los años setenta con el nombre de SEQUEL, como lenguaje del prototipo System R que puso a prueba el modelo relacional de Codd. Lo normalizó ANSI en 1986 e ISO en 1987, y desde entonces la norma se ha revisado varias veces:
| Edición | Lo que trajo |
|---|---|
| SQL-86 y SQL-89 | Las primeras normalizaciones; integridad referencial en la segunda. |
| SQL-92 | La revisión grande, y la que todavía se cita como «SQL estándar»: combinaciones explícitas, subconsultas, el esquema de información. |
| SQL:1999 | Disparadores, consultas recursivas, tipos definidos por el usuario y extensiones objeto-relacionales. |
| SQL:2003 | XML, funciones de ventana, columnas generadas y secuencias. |
| SQL:2006, SQL:2008 | Más XML; INSTEAD OF y ordenación dentro de la ventana. |
| SQL:2011 | Datos temporales: tablas con periodo de validez. |
| SQL:2016 | JSON y reconocimiento de patrones sobre filas. |
| SQL:2023 | La novena edición, adoptada formalmente en junio de 2023: añade el tipo de dato JSON y una parte enteramente nueva para consultar grafos de propiedades. |
Dos cosas conviene retener de esta lista, porque el tribunal las ha usado. La primera: los disparadores no estaban en el SQL original, llegaron con la edición de 1999, y por eso cada fabricante había inventado antes su propia sintaxis, que es la razón de que hoy sigan sin parecerse del todo. La segunda: ninguna implementación cumple la norma entera. Todos los gestores implementan un núcleo común y añaden extensiones propias, así que una sentencia que funciona en un producto puede no compilar en otro. Cuando el enunciado dice «en el estándar ANSI SQL» está pidiendo la forma normalizada; cuando dice «en Oracle» o «en SQL Server», la del dialecto.
2.2. ISO/IEC 9075 y sus partes
La norma vigente es ISO/IEC 9075 y está dividida en partes numeradas, de las que once están activas:
| Parte | Nombre | De qué trata |
|---|---|---|
| 1 | SQL/Framework | Marco general y conceptos comunes a todas las partes. |
| 2 | SQL/Foundation | El lenguaje propiamente dicho: tipos, sentencias y semántica. Es la parte grande y la única imprescindible. |
| 3 | SQL/CLI | Interfaz de nivel de llamada. Es la base de ODBC. |
| 4 | SQL/PSM | Módulos almacenados persistentes: procedimientos, funciones y estructuras de control. Es la parte de este tema. |
| 9 | SQL/MED | Gestión de datos externos al propio gestor. |
| 10 | SQL/OLB | Enlace con lenguajes orientados a objetos. |
| 11 | SQL/Schemata | El esquema de información, es decir, el catálogo normalizado. |
| 13 | SQL/JRT | Rutinas y tipos escritos en Java. |
| 14 | SQL/XML | Todo lo relacionado con XML. |
| 15 | SQL/MDA | Matrices multidimensionales. |
| 16 | SQL/PGQ | Consultas sobre grafos de propiedades. Es la novedad de SQL:2023. |
Las partes 6, 7, 8 y 12 se proyectaron y nunca llegaron a publicarse; la 5 se fundió dentro de la parte 2. Y en la práctica solo tres tienen implantación amplia: la 2, la 11 y la 14. La parte 4, la de los módulos almacenados, es la que define cómo debería escribirse un procedimiento almacenado; ningún fabricante la sigue al pie de la letra, y de ahí que PL/SQL y Transact-SQL se parezcan tan poco.
2.3. Los cinco sublenguajes
SQL no es un lenguaje monolítico: sus sentencias se agrupan por lo que hacen, y el tribunal pregunta a qué grupo pertenece una sentencia concreta. Esta tabla hay que llevarla aprendida de memoria.
| Sublenguaje | Para qué sirve | Sentencias |
|---|---|---|
| DDL Data Definition Language | Definir y modificar la estructura de los objetos. | CREATE, ALTER, DROP, TRUNCATE, RENAME, COMMENT |
| DML Data Manipulation Language | Manipular los datos guardados en las tablas. | INSERT, UPDATE, DELETE, MERGE y —en la clasificación que usa el tribunal— SELECT |
| DQL Data Query Language | Consultar. Muchos autores separan aquí el SELECT; otros lo dejan en DML. | SELECT |
| DCL Data Control Language | Conceder y retirar privilegios. | GRANT, REVOKE y, en Transact-SQL, DENY |
| TCL Transaction Control Language | Delimitar y cerrar transacciones. | COMMIT, ROLLBACK, SAVEPOINT, SET TRANSACTION |
🚨 Los tres puntos exactos donde el tribunal ha construido la trampa, cada uno preguntado más de una vez:
- SELECT es DML. En 2024, en los dos modelos, la pregunta «referente a los comandos DML, señale la respuesta correcta» tenía como buena, literalmente, «el comando SELECT es un comando DML». Si en las opciones aparece DQL como categoría propia hay que leer con calma, pero cuando el enunciado pregunta si SELECT es DML, la respuesta que se da por buena es que sí.
- TRUNCATE es DDL, no DML. Borra todas las filas, pero lo hace desasignando páginas enteras, sin registrar fila a fila, y por eso se clasifica con lo que toca la estructura. En esa misma pregunta, «el comando TRUNCATE es un comando DML» era una de las opciones falsas.
- DENY es DCL. Cayó en los dos modelos de 2026 con esa forma exacta: «¿a qué tipo de comandos SQL pertenece la instrucción DENY en Transact-SQL?». Es DCL, y los distractores eran DQL, DML y TCL. Conviene retener además que DENY es propio de Transact-SQL —la norma solo tiene GRANT y REVOKE— y que es más fuerte que la simple ausencia de permiso: prevalece sobre cualquier concesión recibida por pertenecer a un rol.
2.4. Cómo se escribe una sentencia
Antes de las sentencias, las reglas de escritura, que también se preguntan porque el tribunal esconde la errata en ellas:
- Las palabras clave no distinguen mayúsculas de minúsculas, y por convenio se escriben en mayúsculas para que destaquen. Los nombres de tabla y columna dependen del gestor: Oracle los pasa a mayúsculas salvo que vayan entre comillas dobles, y otros distinguen o no según su configuración.
- Las cadenas de texto van entre comillas simples, siempre, y bien cerradas. Una comilla simple dentro del texto se escribe duplicándola.
- ⚠️ Ahí está la errata que el tribunal puso en 2024, en tres modelos: entre las cuatro formas de escribir un INSERT, la falsa se distinguía porque una de las cadenas abría comilla y no la cerraba. La forma correcta era INSERT INTO CuerpoBecado (Codigo, Denominacion) VALUES ('TAI', 'Técnico Auxiliar de Informática');, con las dos comillas de cada cadena en su sitio, y las opciones falsas o quitaban las comillas o se dejaban una a medias.
- El punto y coma cierra la sentencia. En la mayoría de las herramientas es obligatorio cuando se envían varias seguidas.
- Los comentarios se escriben con dos guiones para una línea, y entre barra-asterisco y asterisco-barra para varias.
- Los identificadores no pueden coincidir con palabras reservadas; si hace falta, se encierran entre comillas dobles en la norma, entre corchetes en Transact-SQL y entre acentos graves en MySQL.
2.5. Los tipos de datos de la norma
La parte 2 fija los tipos predefinidos, y elegir bien no es cuestión de gusto: cada uno tiene una consecuencia física.
| Familia | Tipos | Lo que hay que saber |
|---|---|---|
| Cadenas de caracteres | CHAR(n), VARCHAR(n), CLOB, y las variantes nacionales | CHAR es de longitud FIJA y rellena con espacios hasta n; VARCHAR es de longitud VARIABLE y solo ocupa lo que hay. El primero conviene cuando todos los valores miden lo mismo, como un código de provincia. |
| Numéricos exactos | SMALLINT, INTEGER, BIGINT, NUMERIC(p,e), DECIMAL(p,e) | Guardan precisión —dígitos totales— y escala —decimales— de forma exacta. Son los que hay que usar para importes. |
| Numéricos aproximados | REAL, DOUBLE PRECISION, FLOAT(p) | Coma flotante binaria: arrastran error de redondeo y no representan exactamente una décima. |
| Fecha y hora | DATE, TIME, TIMESTAMP, INTERVAL, y las variantes con zona horaria | El sello de tiempo lleva fecha y hora con fracciones de segundo; el intervalo representa duraciones, no instantes. |
| Otros | BOOLEAN, BLOB, XML, JSON, ARRAY y MULTISET | El tipo JSON es la novedad de la novena edición; antes cada fabricante lo resolvía a su manera. |
Un detalle de examen que aparece en los supuestos: una columna alfanumérica de 2.000 caracteres se declara VARCHAR(2000), y una numérica grande, bigint. En 2024, en dos modelos, la sentencia correcta para crear una tabla con dos columnas numéricas y una alfanumérica larga era exactamente CREATE TABLE Subsanacion (IdSubsanacion bigint, IdSolicitudBeca bigint, TextoFundamento varchar(2000));, y las falsas o se comían la palabra TABLE, o metían un NEW que no existe, o añadían un AS delante del paréntesis.
2.6. El valor nulo y la lógica de tres estados
Por encima de todos los tipos está el valor nulo, que no es un valor sino la ausencia de él, y que obliga a razonar con tres estados —cierto, falso y desconocido— en lugar de dos. Sus consecuencias se preguntan una a una:
- Un nulo no es igual a otro nulo. La comparación se escribe IS NULL y nunca con el operador de igualdad: escribir «= NULL» no da error, da siempre desconocido, y por tanto ninguna fila.
- Cualquier operación aritmética con un nulo devuelve nulo. Sumar un importe conocido y uno desconocido da desconocido.
- Las funciones de agregación ignoran los nulos, con una excepción capital: COUNT(*) los cuenta, porque no mira ninguna columna concreta sino la fila entera.
- En el ORDER BY, cada gestor decide si los nulos van al principio o al final, y la norma permite forzarlo con NULLS FIRST y NULLS LAST.
- En una clave primaria no puede haber nulos —es la regla de integridad de entidad—, y en una clave ajena sí, siempre que lo esté por completo.
Para trabajar con ellos están COALESCE, que devuelve el primer argumento no nulo de una lista, y NULLIF, que devuelve nulo si sus dos argumentos son iguales. Oracle añade NVL y Transact-SQL, ISNULL, que hacen lo mismo con otro nombre.
3. DDL: definir la base de datos
3.1. CREATE TABLE y las restricciones
La creación de una tabla lleva, en la misma sentencia, los nombres de las columnas, sus tipos y las restricciones que deben cumplir:
CREATE TABLE Alumno (
id_alumno INT NOT NULL PRIMARY KEY,
dni CHAR(9) NOT NULL UNIQUE,
nombre VARCHAR(50) NOT NULL,
fecha_alta DATE DEFAULT CURRENT_DATE,
id_centro INT REFERENCES Centro(id_centro)
ON DELETE SET NULL,
CONSTRAINT ck_nombre CHECK (LENGTH(nombre) > 1)
);
Las restricciones declarables son seis, y conviene saber qué garantiza cada una:
| Restricción | Qué garantiza |
|---|---|
| PRIMARY KEY | Identificación única de cada fila. Implica unicidad y ausencia de nulos, y solo puede haber una por tabla. |
| FOREIGN KEY … REFERENCES | Que el valor exista en la clave primaria de la tabla referenciada, o sea enteramente nulo. |
| UNIQUE | Que no haya valores repetidos. A diferencia de la clave primaria, sí admite nulos y puede haber varias por tabla. |
| NOT NULL | Que la columna tenga siempre valor. |
| CHECK | Que el valor cumpla una condición escrita por el diseñador. |
| DEFAULT | Qué valor se pone si la inserción no dice nada. No es una restricción en sentido estricto, pero se declara igual. |
La integridad referencial no se limita a impedir el valor huérfano: dice también qué hacer cuando se borra o se modifica la fila referenciada. Las acciones son NO ACTION o RESTRICT —rechaza la operación—, CASCADE —propaga el borrado o el cambio—, SET NULL y SET DEFAULT. Se declaran con ON DELETE y ON UPDATE, y elegir CASCADE a la ligera es una de las decisiones que más disgustos da: un borrado en la tabla padre puede vaciar media base de datos sin avisar.
🚨 La pregunta de 2026, en los dos modelos, pedía garantizar que el DNI de una tabla no se repitiera y asegurar el máximo rendimiento en las búsquedas por ese campo. La respuesta es ALTER TABLE ALUMNO ADD CONSTRAINT dni_unique UNIQUE (dni);, y merece la pena desmontar por qué las otras tres no valen:
- CREATE INDEX idx_dni ON ALUMNO (dni); acelera la búsqueda, sí, pero no impide los duplicados. Para eso habría que crear el índice como único.
- ALTER TABLE ALUMNO MODIFY dni PRIMARY KEY; no es la sintaxis para añadir una clave primaria y, además, la tabla ya tiene la suya: no puede haber dos.
- Una vista con SELECT DISTINCT oculta los duplicados al consultar, pero no evita que se inserten. El dato sigue estando mal en la tabla.
Y hay una segunda razón por la que la buena es la buena, y es la que el enunciado escondía en «máximo rendimiento»: al declarar una restricción de unicidad, el gestor crea automáticamente un índice para poder comprobarla. Se consiguen las dos cosas con una sola sentencia.
3.2. ALTER TABLE
Modifica la estructura de una tabla ya creada, y sus variantes son las mismas en todos los gestores aunque cambie alguna palabra:
- ADD una columna nueva o una restricción.
- DROP COLUMN o DROP CONSTRAINT para quitarlas.
- ALTER COLUMN en la norma y en Transact-SQL, MODIFY en Oracle y en MySQL, para cambiar el tipo o la nulabilidad.
- RENAME de la tabla o de una columna.
Dos avisos prácticos. El primero: añadir una columna NOT NULL a una tabla con filas exige darle un valor por omisión, porque si no las filas existentes quedarían en un estado imposible. El segundo: en tablas grandes, algunas modificaciones reescriben la tabla entera y bloquean el acceso mientras tanto, así que en producción se planifican como cualquier otra operación de riesgo.
3.3. DROP, TRUNCATE y DELETE: la tabla que se pregunta
Las tres vacían o eliminan, y el tribunal las ha cruzado en varias convocatorias. Esta tabla resuelve por sí sola tres preguntas oficiales:
| DELETE | TRUNCATE | DROP | |
|---|---|---|---|
| Sublenguaje | DML | DDL | DDL |
| Qué elimina | Filas, dejando intacta la definición | Todas las filas de golpe | La estructura del objeto junto con todos sus datos |
| ¿Admite WHERE? | Sí | No | No |
| Registro | Fila a fila; se puede deshacer | Desasigna páginas; normalmente no se deshace | No procede |
| Dispara triggers | Sí | No | No (salvo triggers de DDL) |
🚨 De aquí salen dos preguntas repetidas. La de 2024, en dos modelos: «referente al comando DROP, es correcto decir…» → se utiliza para eliminar la estructura de una tabla junto con cualquier dato almacenado en ella; las falsas decían que es DCL, que usa WHERE y que puede ejecutarlo un disparador. Y la de 2023: «con respecto a las sentencias del lenguaje SQL, indique la INCORRECTA» → la falsa era «DELETE sirve para borrar objetos como bases de datos, tablas o índices», porque eso es DROP: DELETE borra filas, no objetos. En la misma familia cayó también, sin adornos, cuál es la sentencia que elimina los datos de una tabla pero no su definición: DELETE.
3.4. Índices
Un índice es una estructura auxiliar que acelera la búsqueda a costa de espacio y de penalizar las escrituras, porque cada inserción, modificación o borrado tiene que mantenerlo. Se crean y se destruyen con DDL:
CREATE INDEX idx_alumno_centro ON Alumno (id_centro); CREATE UNIQUE INDEX idx_alumno_dni ON Alumno (dni); DROP INDEX idx_alumno_centro;
Los tipos que hay que reconocer son los de siempre —árbol B+ para igualdad y sobre todo para rangos y ordenación, hash solo para igualdad exacta, mapa de bits para columnas de baja cardinalidad en entornos de consulta, y agrupado, que ordena físicamente la tabla y por eso solo puede haber uno—. Y dos matices que deciden si un índice sirve o no sirve para una consulta concreta: un índice compuesto solo aprovecha el prefijo por la izquierda de sus columnas, y un índice cubridor es el que contiene todas las columnas que la consulta necesita, de modo que el gestor la resuelve sin tocar la tabla.
3.5. Vistas
Una vista es una tabla virtual definida por una consulta. No almacena datos —salvo que sea materializada—, y sirve para tres cosas: simplificar consultas complicadas, presentar el nivel externo de la arquitectura de tres esquemas y, sobre todo, como instrumento de seguridad, porque se concede el permiso sobre la vista y no sobre la tabla, ocultando columnas sensibles o limitando las filas visibles.
🚨 La pregunta de 2026 pedía crear una vista que dijera cuántos expedientes ha tramitado cada usuario, y la buena era:
CREATE VIEW ExpTramitados AS SELECT IdUsuarioTramitador, COUNT(IdExpediente) FROM Expedientes GROUP BY IdUsuarioTramitador;
Las tres falsas fallaban en lo mismo que falla siempre la gente con la agregación: una agrupaba sin agrupar —ponía la columna en el SELECT y se olvidaba del GROUP BY—, otra no agregaba nada y se limitaba a listar los identificadores, y la tercera usaba SUM en lugar de COUNT, con lo que habría sumado los números de expediente en vez de contarlos. Volveremos sobre esa regla en el apartado de agregación, porque es la que más veces ha caído del tema.
3.6. Secuencias, identidades y autoincremento
Casi ninguna tabla quiere que el usuario invente la clave primaria, así que todos los gestores ofrecen alguna forma de generarla, y cada uno la llama de una manera:
| Gestor | Mecanismo |
|---|---|
| Norma y Oracle | Secuencias: objetos independientes de la tabla, con CREATE SEQUENCE y las funciones de valor siguiente y valor actual. Desde SQL:2003 existe además la columna de identidad. |
| SQL Server | Columna IDENTITY, y también secuencias. |
| MySQL y MariaDB | AUTO_INCREMENT en la definición de la columna. |
| PostgreSQL | Tipos seriales y columnas de identidad, apoyados en secuencias. |
🚨 Cayó en 2024, en tres modelos, la forma de crear en MySQL una tabla con clave autonumérica, y la buena era CREATE TABLE ProfesoresIngles (id INT NOT NULL PRIMARY KEY AUTO_INCREMENT, nombre VARCHAR(30), apellido1 VARCHAR(30), apellido2 VARCHAR(30));. Las falsas ni siquiera respetaban la sintaxis: una escribía la palabra KEY suelta detrás del nombre de la tabla, otra traducía la sentencia al español y la tercera declaraba columnas sin tipo.
Y un detalle de administración que también ha caído: en SQL Server, cuando la secuencia de identidad de una tabla se desajusta —típicamente tras unas pruebas en preproducción—, se comprueba y se reinicia con DBCC CHECKIDENT. Los distractores inventaban una orden llamada RESETIDENT, que no existe, y añadían el parámetro que precisamente impide reiniciar el contador.
3.7. El catálogo del sistema
La base de datos se describe a sí misma, y esa descripción se consulta con el mismo lenguaje que los datos —es la cuarta regla de Codd—. Cada gestor lo expone a su manera:
- La norma define el esquema de información (parte 11), con vistas como TABLES, COLUMNS y TABLE_CONSTRAINTS. Lo implementan SQL Server, MySQL y PostgreSQL.
- Oracle tiene las vistas del diccionario con tres prefijos: USER_ para lo que es del usuario, ALL_ para lo que puede ver y DBA_ para todo.
- SQL Server añade las vistas de catálogo con el prefijo sys.
- MySQL guarda las cuentas en la base de datos de sistema del mismo nombre. 🚨 De ahí sale la pregunta de 2024, en tres modelos: para saber qué usuarios acceden a la base de datos y desde qué máquina, la consulta es SELECT user, host FROM mysql.user. La clave está en la palabra host: en MySQL la identidad de una cuenta es el par usuario más máquina, de modo que la misma cuenta desde dos sitios distintos son dos cuentas distintas, y una consulta que pida solo el usuario deja fuera la mitad de la respuesta.
4. DML y DQL: consultar y manipular
4.1. INSERT, UPDATE, DELETE y MERGE
Las cuatro sentencias que cambian datos. Van con su forma exacta, porque el tribunal las pone literales:
INSERT INTO CuerpoBecado (Codigo, Denominacion)
VALUES ('TAI', 'Técnico Auxiliar de Informática');
INSERT INTO Historico (id, nombre)
SELECT id, nombre FROM Alumno WHERE fecha_alta < DATE '2020-01-01';
UPDATE Alumno SET id_centro = 7 WHERE id_alumno = 1024;
DELETE FROM Alumno WHERE fecha_alta < DATE '2010-01-01';
Cuatro reglas que se preguntan:
- La lista de columnas del INSERT es opcional, pero omitirla obliga a dar todos los valores en el orden exacto de la tabla. Escribirla siempre es la práctica sana, porque sobrevive a que alguien añada una columna.
- Un INSERT puede tomar sus valores de un SELECT en vez de una lista literal, y esa es la forma de copiar datos de una tabla a otra.
- UPDATE y DELETE sin WHERE afectan a TODAS las filas. No es un error de sintaxis, así que el gestor no avisa: es el accidente clásico de la administración de bases de datos.
- MERGE —también llamada upsert— combina las tres: actualiza la fila si existe e inserta si no. Está en la norma desde SQL:2003.
4.2. SELECT: el orden que se escribe y el que se evalúa
La consulta es la sentencia central del lenguaje, y su rasgo más contraintuitivo es que el orden en que se escriben sus cláusulas no es el orden en que se evalúan:
| Se escribe | Se evalúa |
|---|---|
| SELECT → FROM → WHERE → GROUP BY → HAVING → ORDER BY | FROM → WHERE → GROUP BY → HAVING → SELECT → ORDER BY |
De ese desajuste salen tres consecuencias que explican casi todos los errores de principiante:
- No se puede usar en el WHERE un alias definido en el SELECT, porque cuando se filtra la lista de columnas todavía no se ha resuelto. Sí se puede usar en el ORDER BY, que es lo último.
- No se puede filtrar por una función de agregación en el WHERE, porque los grupos aún no existen: para eso está HAVING, que actúa después de agrupar.
- El DISTINCT se aplica al resultado del SELECT, así que elimina filas duplicadas del resultado, no de la tabla.
4.3. WHERE y sus operadores
La condición de filtro admite los operadores de comparación de siempre y, además, cinco construcciones propias del lenguaje:
| Operador | Qué hace | Detalle que se pregunta |
|---|---|---|
| BETWEEN a AND b | Rango | Es inclusivo en los dos extremos. |
| IN (lista) | Pertenencia a un conjunto | La lista puede ser literal o el resultado de una subconsulta. ⚠️ Con nulos dentro, NOT IN se comporta de forma sorprendente y no devuelve nada. |
| LIKE 'patrón' | Comparación de cadenas con comodines | El tanto por ciento sustituye a cualquier número de caracteres, incluido ninguno; el guion bajo, a uno solo. |
| IS NULL | Ausencia de valor | La única forma correcta de preguntar por un nulo. |
| EXISTS (subconsulta) | Si la subconsulta devuelve al menos una fila | No importa qué devuelva, solo si devuelve algo. |
🚨 El LIKE cayó en 2024, en dos modelos, y con una trampa doble. Había que localizar los ficheros adjuntos de una solicitud que NO fueran PDF, y la buena escribía NOT LIKE '%.pdf'. Dos cosas importan de esa cadena: el NOT, porque la opción que ponía LIKE a secas devolvía exactamente lo contrario de lo pedido; y el comodín inicial, porque sin él el patrón exigiría que el nombre empezara por el punto y no encontraría nada. La opción falsa más fina escribía NOT LIKE 'pdf', sin comodín ninguno, que solo casaría con un fichero llamado literalmente así. Y la cuarta fallaba en la subconsulta anidada: se dejaba el FROM de la tabla interior, con lo que la sentencia ni siquiera es válida.
4.4. Combinaciones
Combinar es traer a la misma fila datos de dos tablas relacionadas. Los tipos son estos, y elegir mal cambia el resultado:
| Combinación | Qué devuelve |
|---|---|
| INNER JOIN | Solo las filas con correspondencia en ambas tablas. Es la que responde a «los alumnos que tienen matrículas». |
| LEFT OUTER JOIN | Todas las de la izquierda; las de la derecha que no casan salen a nulo. Añadiendo IS NULL se obtiene justo lo contrario: «los que NO tienen». |
| RIGHT OUTER JOIN | La simétrica de la anterior. |
| FULL OUTER JOIN | Todas las filas de los dos lados, casen o no. |
| CROSS JOIN | Producto cartesiano: cada fila con cada fila. Es lo que ocurre sin querer al escribir dos tablas separadas por coma y olvidar la condición de enlace. |
| SELF JOIN | Una tabla consigo misma, con alias distintos. Es la forma de sacar el empleado y su jefe. |
| NATURAL JOIN | Combina por las columnas que se llaman igual en las dos tablas. Cómodo y peligroso: si alguien añade una columna con nombre coincidente, la consulta cambia de significado en silencio. |
🚨 La pregunta de 2026, en los dos modelos, pedía «solamente los datos de todos los alumnos que tienen matrículas asociadas», y la buena era:
SELECT * FROM ALUMNO INNER JOIN MATRICULA ON ALUMNO.id_alumno = MATRICULA.id_alumno;
Las tres falsas repasaban los errores clásicos: SELECT * FROM ALUMNO, MATRICULA; es un producto cartesiano sin condición de enlace y devuelve todas las combinaciones posibles; WHERE id_alumno IN MATRICULA no es sintaxis válida, porque el operador de pertenencia necesita una lista o una subconsulta completa, no un nombre de tabla suelto; y la última consultaba la tabla de matrículas comparándola con una tabla que no había declarado en su FROM.
4.5. Agregación: GROUP BY y HAVING
Las funciones de agregación resumen un conjunto de filas en un solo valor: COUNT, SUM, AVG, MIN y MAX. Y llevan detrás dos reglas que son, con diferencia, las más preguntadas del tema:
- COUNT(*) cuenta filas, incluidas las que tienen nulos; COUNT(columna) cuenta solo los valores no nulos de esa columna. Es la única agregación que no ignora los nulos, y por eso los dos recuentos dan cifras distintas sobre la misma tabla.
- Toda columna del SELECT que no esté agregada tiene que aparecer en el GROUP BY. No es un consejo de estilo: es lo que hace que la consulta tenga sentido, porque si no el gestor no sabría qué valor mostrar de entre los del grupo.
🚨 La pregunta cayó en los dos modelos de 2026, con el enunciado «número total de matrículas por programa formativo». La buena:
SELECT id_programa, COUNT(*) FROM MATRICULA GROUP BY id_programa;
Y las tres falsas, cada una con su defecto, que conviene reconocer de un vistazo:
- SELECT COUNT(*) FROM MATRICULA GROUP id_programa; — se come el BY. La cláusula se llama GROUP BY, las dos palabras, y sin la segunda no es sintaxis válida.
- SELECT id_programa, COUNT(id_programa) FROM MATRICULA; — no agrupa. Mezcla una columna sin agregar con una función de agregación y no dice por qué agrupar.
- SELECT id_programa, SUM(*) FROM MATRICULA GROUP BY id_programa; — SUM(*) no existe. El asterisco solo lo admite el recuento; sumar exige una expresión numérica concreta.
Para filtrar después de agrupar está HAVING, y ahí es donde sí caben las funciones de agregación:
SELECT id_programa, COUNT(*) AS matriculas FROM MATRICULA GROUP BY id_programa HAVING COUNT(*) > 100 ORDER BY matriculas DESC;
La regla corta para no dudar: WHERE filtra filas antes de agrupar; HAVING filtra grupos después. Poner en el WHERE una condición sobre un recuento es un error de sintaxis, y poner en el HAVING una condición que podría ir en el WHERE es un error de eficiencia, porque obliga a formar grupos que después se descartan.
4.6. Subconsultas
Una subconsulta es una consulta dentro de otra, y puede aparecer en tres sitios:
- En el SELECT, si devuelve un solo valor —subconsulta escalar—.
- En el FROM, como si fuera una tabla; se la llama vista en línea o tabla derivada, y necesita alias.
- En el WHERE, que es el caso habitual, con los operadores IN, NOT IN, EXISTS, NOT EXISTS, ANY, SOME y ALL.
Y se dividen en dos clases que conviene distinguir porque su coste es muy distinto:
| Clase | Cómo funciona |
|---|---|
| No correlacionada | Se puede evaluar por su cuenta, una sola vez, y su resultado se usa después. Es la barata. |
| Correlacionada | Referencia una columna de la consulta exterior, así que se reevalúa para cada fila de esta. Es la que puede dispararse en tablas grandes. |
Un matiz que se pregunta: EXISTS y NOT EXISTS no miran qué devuelve la subconsulta, solo si devuelve algo, y por eso dentro suele escribirse SELECT 1. Y otro que muerde en la práctica: NOT IN con una lista que contenga un nulo no devuelve ninguna fila, porque comparar con desconocido nunca da cierto; NOT EXISTS no tiene ese problema y es la forma segura de escribir «los que no están».
4.7. Operadores de conjuntos
Combinan los resultados de dos consultas y exigen compatibilidad de esquemas: el mismo número de columnas y tipos compatibles, en el mismo orden.
| Operador | Qué devuelve |
|---|---|
| UNION | Las filas de una u otra, eliminando duplicados. |
| UNION ALL | Lo mismo sin eliminarlos. Es más rápida, porque se ahorra la ordenación, y es la que hay que usar cuando se sabe que no hay repetidos. |
| INTERSECT | Las filas presentes en las dos. |
| EXCEPT | Las de la primera que no están en la segunda. Oracle la llama MINUS. |
4.8. CASE, COALESCE y las funciones que caen
La expresión CASE es el condicional de SQL, y es una expresión: devuelve un valor y puede ponerse en cualquier sitio donde quepa una columna.
SELECT IdProceso,
CASE IdFormaAcceso
WHEN 'L' THEN 'Ingreso Libre'
WHEN 'P' THEN 'Promocion Interna'
END AS FormaAcceso
FROM Proceso;
🚨 Esa sentencia es, literal, la respuesta correcta de una pregunta oficial. La opción falsa más tentadora escribía IF … THEN … ELSE … ENDIF, que es sintaxis de un lenguaje procedimental y no existe dentro de una consulta SQL. Hay dos formas de CASE: la simple, que compara una expresión con valores, y la buscada, que evalúa condiciones completas tras cada WHEN. Las dos admiten ELSE y las dos se cierran con END.
Junto a ella, las funciones que el tribunal ha preguntado por su resultado exacto:
- Funciones de cadena: concatenación, longitud, subcadena, mayúsculas y minúsculas, recorte de espacios, sustitución y búsqueda de posición.
- 🚨 De esta última salió una pregunta de 2026 que merece resolverse paso a paso: en Oracle, SELECT INSTR('Corporate Floor','or', 3, 2) FROM DUAL; devuelve 14. La función busca la subcadena indicada dentro de la cadena, empezando por la posición 3 y quedándose con la segunda aparición. En «Corporate Floor» la secuencia buscada aparece en la posición 2 —dentro de «Corporate»—, en la 5 y en la 14, dentro de «Floor»; como se arranca en la 3, la primera que cuenta es la de la posición 5 y la segunda es la de la 14. Los distractores eran justamente las otras posiciones.
- La tabla DUAL de Oracle, que aparece en esa misma sentencia, es una tabla ficticia de una sola fila y una sola columna que existe para poder escribir un SELECT sin tabla real.
- Funciones numéricas y de fecha: redondeo, truncamiento, resto, fecha actual, extracción de partes y diferencias entre fechas.
- Conversión: CAST en la norma, más las funciones propias de cada dialecto.
4.9. Ordenar y quedarse con unas pocas filas
La cláusula que especifica el criterio de ordenación es ORDER BY, con ASC —que es lo predeterminado— o DESC. Cayó tal cual en 2023, con distractores que inventaban formas como «ORDER TO».
Quedarse con las primeras filas, en cambio, es lo único importante del lenguaje que cada dialecto resuelve a su manera:
| Gestor | Cómo se escribe |
|---|---|
| SQL Server | TOP(n), entre el SELECT y la lista de columnas |
| MySQL y PostgreSQL | LIMIT n, al final, con OFFSET para saltar filas |
| La norma y Oracle moderno | FETCH FIRST n ROWS ONLY |
| Oracle clásico | ROWNUM, en el WHERE |
🚨 La pregunta de 2026 pedía «los últimos 10 usuarios dados de alta» en SQL Server, y la buena era:
SELECT TOP(10) Nombre, Apellido1, Apellido2 FROM Usuarios ORDER BY FechaCreacion DESC;
Y aquí está el detalle que decide la pregunta: TOP por sí solo no significa «los últimos». Sin ordenar, devuelve diez filas cualesquiera; ordenando de forma ascendente devuelve los diez primeros. Solo el DESC convierte esa consulta en lo que pedía el enunciado. Una de las opciones falsas ordenaba ascendente y otra filtraba por una fecha fija en lugar de ordenar; la cuarta ni siquiera colocaba el TOP en su sitio.
4.10. Consultas con WITH y consultas recursivas
La cláusula WITH define una expresión de tabla común: una consulta con nombre que se usa después en la principal. No cambia el resultado, cambia la legibilidad, y evita repetir la misma subconsulta tres veces.
WITH matriculas_por_programa AS ( SELECT id_programa, COUNT(*) AS total FROM MATRICULA GROUP BY id_programa ) SELECT * FROM matriculas_por_programa WHERE total > 100;
Su versión interesante es la recursiva, que llegó con SQL:1999 y sirve para recorrer jerarquías —un organigrama, un árbol de expedientes, una lista de materiales—. Se escribe con WITH RECURSIVE y tiene dos partes unidas por UNION ALL: un caso base y un paso recursivo que se refiere a la propia expresión. Es exactamente la misma estructura que una función recursiva, con el mismo riesgo: sin caso base que la detenga, no termina.
4.11. Funciones de ventana
Llegaron con SQL:2003 y resuelven lo que antes obligaba a repetir la consulta: calcular un agregado sin colapsar las filas. La diferencia con GROUP BY es exactamente esa: la agregación normal devuelve una fila por grupo; la de ventana devuelve todas las filas y añade el cálculo en una columna más.
SELECT nombre, id_centro, nota,
RANK() OVER (PARTITION BY id_centro ORDER BY nota DESC) AS puesto
FROM Alumno;
La cláusula OVER es la que las define, y dentro caben PARTITION BY —que agrupa sin colapsar— y ORDER BY —que ordena dentro de cada partición—. Las que conviene reconocer son las de numeración y ranking, las de desplazamiento a la fila anterior o siguiente, y las agregaciones de siempre usadas como ventana para obtener acumulados y medias móviles.
5. DCL y TCL: permisos y transacciones
5.1. Conceder y retirar privilegios
El control de accesos de una base de datos se articula en tres piezas —autenticación (quién eres), autorización (qué puedes hacer) y auditoría (qué has hecho)—, y la segunda se declara con DCL:
GRANT SELECT, INSERT ON Alumno TO rol_gestor; GRANT SELECT ON Alumno TO usuario_informes WITH GRANT OPTION; REVOKE INSERT ON Alumno FROM rol_gestor;
Cuatro cosas que se preguntan:
- Los privilegios se conceden por objeto y por operación, y en las columnas concretas si hace falta. Nada obliga a dar acceso a la tabla entera.
- La cláusula WITH GRANT OPTION permite al beneficiario ceder a su vez el privilegio, y hay que vigilarla porque propaga permisos en cascada: al retirar la concesión original se arrastra lo concedido a partir de ella.
- La buena práctica es el privilegio mínimo: nunca dar al usuario de la aplicación permisos de definición de datos, y agrupar los permisos en roles en lugar de asignarlos usuario a usuario.
- DENY, propio de Transact-SQL, no es lo mismo que no conceder: prohíbe expresamente, y esa prohibición gana a cualquier concesión que el usuario reciba por pertenecer a un rol.
Crear la propia cuenta también es DCL en la práctica, aunque formalmente sea definición de datos. 🚨 Cayó en los dos modelos de 2026 la forma exacta en Oracle: CREATE USER EDUCA_USER IDENTIFIED BY contraseña;. Las falsas inventaban verbos que no existen —REGISTER USER, ADD USER, NEW USER— y una de ellas quitaba además la palabra BY. Es el patrón habitual del tribunal en las preguntas de sintaxis: el verbo correcto es siempre el más aburrido.
5.2. Transacciones
Una transacción es una unidad lógica de trabajo que se ejecuta por completo o no se ejecuta. Empieza de forma implícita o explícita y termina de una de dos maneras:
- COMMIT confirma y hace permanentes los cambios.
- ROLLBACK restituye todas las modificaciones realizadas desde el inicio de la transacción o desde un punto de retorno.
- SAVEPOINT marca ese punto de retorno intermedio, de modo que se puede deshacer solo una parte del trabajo sin perderlo todo.
- SET TRANSACTION fija sus características, entre ellas el nivel de aislamiento.
🚨 Cayó en los dos modelos de 2026 con el enunciado calcado de esa definición: «si se quiere restituir todas las modificaciones de datos realizadas desde el inicio de una transacción, o desde un punto de retorno, se debe usar la sentencia…» → ROLLBACK. Los distractores eran SAVEPOINT —que marca el punto pero no deshace nada—, DELETE —que borra filas y no tiene que ver con transacciones— y un inventado «RETURNBACK». Y en 2019 cayó la otra mitad: para establecer un punto de recuperación dentro de una transacción en Oracle se usa SAVEPOINT. Las dos preguntas son la misma moneda por sus dos caras, y confundirlas cuesta las dos.
5.3. ACID y niveles de aislamiento
Las cuatro garantías de una transacción se resumen en ACID: Atomicidad —todo o nada—, Consistencia —de un estado válido a otro estado válido—, Aislamiento —una transacción en curso no ve los estados intermedios de otra— y Durabilidad —confirmada la transacción, sus efectos sobreviven a cualquier fallo—. ⚠️ La falsificación habitual del acrónimo cambia la D por «disponibilidad», que es la A del teorema CAP y pertenece a otro marco conceptual.
El aislamiento perfecto sería serializar todo el trabajo, y eso mataría la concurrencia, así que la norma define cuatro niveles y tres anomalías que cada uno permite o impide:
| Anomalía | En qué consiste |
|---|---|
| Lectura sucia | Se leen datos que otra transacción ha modificado y todavía no ha confirmado. Si esa otra deshace, lo leído nunca existió. |
| Lectura no repetible | Se lee la misma fila dos veces dentro de la misma transacción y devuelve valores distintos. |
| Lectura fantasma | Se repite la misma consulta de rango y aparecen o desaparecen filas que otra transacción insertó o borró. |
Y la escalera, que resuelve por sí sola varias preguntas oficiales. Cada peldaño elimina una anomalía más y admite menos concurrencia:
| Nivel | Lectura sucia | Lectura no repetible | Lectura fantasma |
|---|---|---|---|
| READ UNCOMMITTED | Posible | Posible | Posible |
| READ COMMITTED | Evitada | Posible | Posible |
| REPEATABLE READ | Evitada | Evitada | Posible |
| SERIALIZABLE | Evitada | Evitada | Evitada |
🚨 La pregunta de la convocatoria extraordinaria de 2026 pedía la sentencia correcta sobre estos niveles, y era: «la lectura repetible protege contra la lectura sucia y la lectura no repetible, pero no contra la lectura fantasma». Las tres falsas invertían siempre lo mismo: que la no confirmada protege contra algo —no protege contra nada—, que la confirmada no protege contra la lectura sucia —sí protege, es lo único que hace— y que serializable deja pasar las no repetibles —no deja pasar ninguna—. Con la tabla memorizada como una escalera, las cuatro se resuelven leyendo.
Por debajo, el gestor consigue el aislamiento de dos maneras: con bloqueos —control pesimista, con bloqueos compartidos de lectura y exclusivos de escritura, y el protocolo de bloqueo en dos fases— o con multiversión —control optimista, donde cada transacción ve una instantánea coherente y los lectores no bloquean a los escritores—. Los bloqueos traen consigo los interbloqueos, que el gestor detecta con un grafo de espera y resuelve eligiendo una víctima a la que deshace.
6. Procedimientos almacenados
6.1. Qué son y para qué sirven
Un procedimiento almacenado es una rutina escrita en el lenguaje procedimental del gestor, compilada y guardada dentro de la propia base de datos, que se invoca por su nombre. La norma los recoge en la parte 4, SQL/PSM, aunque ningún fabricante la sigue al pie de la letra.
Sus ventajas, que se preguntan enumeradas:
- Menos tráfico de red: una llamada sustituye a diez sentencias que irían y volverían por separado.
- Menos trabajo del gestor: el plan de ejecución se calcula una vez y se reutiliza.
- Lógica centralizada: la regla de negocio vive en un solo sitio y no repartida por cada aplicación que ataca la base.
- Seguridad: se puede conceder permiso para ejecutar el procedimiento sin darlo sobre las tablas que toca, con lo que el usuario solo puede hacer lo que el procedimiento le deja.
Y sus inconvenientes, que también: atan la aplicación al gestor, porque el dialecto no es portable; el código queda fuera del control de versiones habitual si nadie se ocupa de meterlo; y depurarlo y probarlo es bastante más incómodo que depurar código de aplicación.
6.2. Procedimiento frente a función
| Función | Procedimiento | |
|---|---|---|
| Devuelve valor | Sí, asociado a su nombre | No necesariamente; puede devolver por sus parámetros |
| Cómo se invoca | Dentro de una expresión, incluso en un SELECT | Como una sentencia, con CALL o EXECUTE |
| Efectos secundarios | Restringidos: muchos gestores no dejan que una función modifique datos | Puede hacer lo que sea |
6.3. Parámetros
Los parámetros de una rutina almacenada se declaran por su modo, y esto es de la norma:
- IN: solo entrada. Es el modo por omisión.
- OUT: solo salida; la rutina escribe en él y el llamante lo recoge.
- INOUT: entra con un valor y sale con otro.
Es exactamente la misma distinción que en cualquier lenguaje de programación, y el paralelismo ayuda a recordarla: un parámetro de entrada equivale al paso por valor y uno de salida o de entrada y salida, al paso por referencia.
6.4. Los dialectos
| Gestor | Lenguaje | Lo que hay que saber |
|---|---|---|
| Oracle | PL/SQL | 🚨 Cayó dos veces con esta definición: es el lenguaje de procedimiento cuya sintaxis permite insertar sentencias SQL y que se almacena compilado dentro de la base de datos. El distractor fue siempre Transact-SQL, que es el de otro fabricante. Su unidad es el bloque, con tres secciones: declaración, ejecución y tratamiento de excepciones. |
| SQL Server | Transact-SQL | DENY como DCL, TOP(n) para limitar filas y los comandos de consola DBCC. Sus procedimientos se crean con CREATE PROCEDURE y se invocan con EXECUTE. |
| PostgreSQL | PL/pgSQL | Muy apegado a la norma. Admite además rutinas escritas en otros lenguajes. |
| MySQL y MariaDB | Procedimientos SQL/PSM | Sintaxis próxima a la norma, con la peculiaridad de tener que cambiar el delimitador para poder escribir el cuerpo. |
🚨 Los tipos de procedimiento almacenado de SQL Server cayeron en la convocatoria extraordinaria de 2026, y son cuatro: definidos por el usuario, temporales, de sistema y extendidos. Las opciones falsas metían «locales», «globales» y «almacenados» —esta última especialmente absurda, porque todos lo son—. Conviene memorizar la lista como una serie, porque el distractor cambia solo una palabra.
6.5. Lo que hay dentro de un procedimiento
El cuerpo de una rutina almacenada es código procedimental corriente, con las piezas de siempre:
- Variables locales, con su declaración y su tipo.
- Control de flujo: condicional, selección múltiple y bucles —mientras, repetir y para—.
- Cursores, que son la manera de recorrer fila a fila el resultado de una consulta. Se abren, se leen en un bucle, se cierran y se liberan. ⚠️ Son la herramienta de último recurso: un cursor convierte una operación de conjunto en un bucle, y casi siempre hay una sentencia SQL que hace lo mismo mucho más rápido. La regla práctica es escribir en conjuntos y bajar al cursor solo cuando no haya otra.
- Tratamiento de excepciones, con la misma estructura que en cualquier lenguaje: se captura el error, se decide qué hacer y, si procede, se deshace la transacción.
🚨 El nombre de esa captura cambia con el motor, y es preguntable. En Oracle la sección se llama EXCEPTION y va dentro del propio bloque, entre el código y el END; en SQL Server no hay sección, sino dos bloques consecutivos, BEGIN TRY con el código que puede fallar y BEGIN CATCH con lo que hacer si falla, y dentro del segundo se consultan funciones como ERROR_NUMBER y ERROR_MESSAGE. MySQL usa una tercera forma, el DECLARE … HANDLER, que se declara arriba y se activa cuando aparece la condición indicada.
⚠️ Lo que no cambia es lo importante: la captura no deshace nada por su cuenta. Si dentro del CATCH o del EXCEPTION no se escribe un ROLLBACK, la transacción sigue abierta con los cambios a medias, y el error queda tapado sin que nadie se entere. Es el fallo clásico del procedimiento que «no da error» y deja los datos incoherentes.
6.6. Sentencias preparadas y SQL dinámico
Una sentencia preparada es una sentencia que se envía al gestor una vez con marcadores en lugar de valores, se analiza y se planifica una vez, y después se ejecuta muchas veces con valores distintos. 🚨 Esa es literalmente la respuesta que dio por buena el tribunal: su finalidad es permitir ejecutar muchas veces una sentencia SQL.
Tiene dos ventajas y la segunda es la importante:
- Rendimiento: se ahorra el análisis y la optimización en cada ejecución.
- Seguridad: el valor viaja separado del texto de la sentencia, así que el gestor nunca lo interpreta como código. Es la contramedida principal contra la inyección SQL, y no filtrar comillas, que es un parche que se sortea de varias maneras.
Su opuesto es el SQL dinámico: construir el texto de la sentencia concatenando cadenas en tiempo de ejecución. A veces hace falta —cuando el nombre de la tabla o el criterio de ordenación no se conocen hasta ejecutar—, pero es exactamente el terreno donde nace la inyección, así que lo que venga de fuera se valida contra una lista cerrada de valores admitidos, nunca se concatena tal cual.
6.7. Dos características de SQL Server que ha preguntado el tribunal
- Machine Learning Services es la característica que permite ejecutar scripts de Python y de R sobre datos relacionales, dentro del propio motor. Cayó en 2023, y el distractor describía la replicación, que es otra cosa: el conjunto de tecnologías destinadas a copiar y distribuir datos y objetos de una base de datos a otra y mantenerlas después sincronizadas. Del paquete de R para trabajar a escala dentro del motor también se preguntó el nombre.
- DBCC es la familia de comandos de consola de la base de datos, y de ella salió la pregunta de CHECKIDENT ya vista, para comprobar y reiniciar el valor de identidad de una tabla.
7. Disparadores
7.1. Qué es y cómo se declara
Un disparador o trigger es un procedimiento que se ejecuta automáticamente cuando ocurre un evento determinado sobre una tabla determinada. Nadie lo invoca: se dispara solo. Y esa es su virtud y su peligro, porque el efecto ocurre lejos del código que lo provocó.
La sintaxis del estándar ANSI empieza por el nombre, sigue con el momento y el evento y termina con ON y la tabla, sin la palabra TABLE:
CREATE TRIGGER Validar_cambio BEFORE UPDATE ON Departamento CREATE TRIGGER Validar_salario BEFORE UPDATE OF Salario ON Empleados
🚨 Esta pregunta ha caído tres veces —en los dos modelos de 2026 y en 2019— y siempre con las mismas cuatro opciones casi idénticas. Las tres falsas son estas, y conviene reconocerlas de un vistazo:
- CREATE TRIGGER … BEFORE UPDATE OF TABLE Departamento — la palabra OF existe, pero introduce la columna vigilada, no la tabla.
- CREATE TRIGGER … ON TABLE Departamento BEFORE UPDATE — sobra la palabra TABLE y, además, el momento y el evento van antes del ON, no después.
- CREATE NEW TRIGGER … OF Departamento BEFORE UPDATE — ni existe el NEW ni el OF introduce tablas.
La segunda variante de la sentencia, la que vigila una columna concreta, coloca OF Salario entre el evento y el ON. En 2019 el tribunal la preguntó así, y la opción falsa más fina cambiaba el ON por IN.
7.2. Las tres decisiones de un disparador
| Decisión | Opciones | Para qué |
|---|---|---|
| Evento | INSERT, UPDATE y DELETE | Son los tres eventos de manipulación que pueden activarlo. Pueden combinarse. |
| Momento | BEFORE, AFTER y, sobre vistas, INSTEAD OF | Antes sirve para validar o completar valores; después, para propagar o auditar. El tercero sustituye a la operación, y es lo que hace actualizable una vista que no lo sería. |
| Granularidad | FOR EACH ROW o por sentencia | Por fila se ejecuta una vez por cada fila afectada; por sentencia, una sola vez aunque la sentencia toque mil filas. |
Dentro del cuerpo, el disparador accede a los valores implicados mediante dos referencias: OLD, con la fila como estaba, y NEW, con la fila como va a quedar. En un INSERT no hay OLD; en un DELETE no hay NEW. Transact-SQL lo resuelve de otra manera, con dos tablas virtuales llamadas inserted y deleted.
7.3. El disparador y la transacción
🚨 Este es el punto más preguntado del epígrafe, y cayó en tres modelos de 2024 pidiendo señalar la afirmación INCORRECTA. La falsa decía: «un error durante la ejecución de cualquier trigger no cancela automáticamente la operación que lo disparó, la cancelación hay que programarla». Es falsa porque ocurre justo lo contrario: el disparador forma parte de la misma transacción que la sentencia que lo activó, así que si él falla, falla todo el conjunto y la operación se deshace sin que nadie programe nada.
Las otras tres opciones de esa pregunta eran ciertas y merecen retenerse como definición: que son procedimientos que se ejecutan cada vez que ocurre un evento determinado sobre una tabla determinada; que los eventos que pueden asociarse son INSERT, UPDATE y DELETE; y que puede decidirse si se activan antes o después del evento.
7.4. Tipos de disparador en SQL Server
🚨 En la convocatoria extraordinaria de 2026 se preguntó qué tipos contempla SQL Server, y son tres: DML, DDL y LOGON.
- DML: los de siempre, sobre inserciones, modificaciones y borrados de una tabla o vista.
- DDL: se disparan ante sentencias que cambian la estructura —crear, alterar o eliminar objetos—, y son la herramienta con la que se audita quién toca el esquema.
- LOGON: se disparan al iniciar sesión, y sirven para restringir conexiones o llevar su registro.
Los distractores inventaban categorías que suenan razonables —«DMC», «EXTENDS», «AFTER», «DMZ»— y una de ellas colaba como tipo lo que en realidad es un momento. Es el patrón de siempre: la opción falsa mezcla la clasificación buena con un término de otra dimensión.
7.5. Usos, abusos y el precio de un disparador
Los usos legítimos son cuatro: validar reglas de negocio que una restricción declarativa no puede expresar, auditar quién cambió qué y cuándo, mantener datos derivados —un contador, un total— y propagar cambios a tablas relacionadas cuando la integridad referencial no basta.
Y los precios, que conviene saber enumerar:
- Efectos invisibles. Quien lee la aplicación no ve el disparador, así que un comportamiento inexplicable puede estar escrito en un sitio donde nadie mira.
- Disparadores en cascada. Un disparador que escribe en otra tabla puede activar el disparador de esa tabla, y así sucesivamente. Los gestores limitan la profundidad, pero el diseño ya es frágil antes de llegar al límite.
- Coste por fila. Un disparador por fila sobre una carga masiva multiplica el trabajo por el número de filas.
- El problema de la tabla mutante de Oracle: un disparador por fila no puede consultar la tabla que lo disparó mientras la sentencia sigue en curso, porque vería un estado a medias.
La regla razonable: lo que pueda declararse como restricción, se declara —una comprobación o una clave ajena son más baratas, más claras y las optimiza el gestor—, y el disparador se reserva para lo que de verdad no cabe en una restricción.
8. Eventos programados
Un evento es una tarea que la propia base de datos ejecuta en un momento programado, sin que nadie la llame y sin depender del planificador del sistema operativo. Es la contrapartida temporal del disparador: uno reacciona a un suceso de datos y el otro, al reloj.
En MySQL se crean con CREATE EVENT y su temporalidad se indica en la cláusula ON SCHEDULE, que admite una ejecución única en un instante dado o una repetición cada cierto intervalo. Hace falta que el planificador de eventos esté activado, cosa que no lo está por omisión.
🚨 La pregunta de 2024 pedía señalar la afirmación INCORRECTA sobre los eventos, y la falsa era: «una vez que el evento se ha ejecutado hay que eliminarlo manualmente». No: un evento de ejecución única se elimina solo al terminar, salvo que se declare expresamente lo contrario con la cláusula de preservación al completarse. Las opciones ciertas incluían que la temporalidad se indica en ON SCHEDULE, que es de las que conviene retener con su nombre exacto.
Los demás gestores resuelven lo mismo con otras piezas, y el tribunal las ha nombrado de pasada: Oracle tiene su planificador propio dentro del gestor, y SQL Server lo saca fuera del motor, a un servicio de agente que ejecuta trabajos programados. Y en el mundo Unix siempre queda la alternativa externa de programar la tarea con el demonio del sistema, que es más simple pero deja la lógica repartida entre dos sitios.
9. Los otros lenguajes de interrogación
9.1. OQL, el de las bases de datos de objetos
OQL es el lenguaje de consulta que define el estándar ODMG 3.0 para las bases de datos orientadas a objetos, junto al lenguaje de definición ODL y al modelo de objetos. 🚨 El tribunal lo preguntó en los dos modelos de 2024 y la respuesta es que es un lenguaje de consulta de datos —no de definición, no de manipulación—.
Su sintaxis se parece deliberadamente a la de SQL, pero con dos diferencias de fondo: devuelve objetos en vez de filas, y permite navegar por las referencias con la notación de punto en lugar de reunir tablas. Donde SQL escribiría una combinación entre dos tablas, OQL escribe el atributo del atributo.
9.2. XQuery y XPath, los del XML
XPath localiza partes de un documento XML mediante expresiones de camino; XQuery lo usa como base y añade un lenguaje de consulta completo, con su construcción característica de cinco cláusulas —recorrer, ligar, filtrar, ordenar y devolver—. Están normalizados por el W3C, y la parte 14 de SQL define además cómo conviven con el mundo relacional: cómo se guarda un XML en una columna y cómo se consulta desde SQL.
9.3. CQL, el de Cassandra
CQL es el lenguaje de Apache Cassandra, una base de datos de familias de columnas. Su sintaxis imita a propósito la de SQL —tiene SELECT, INSERT, UPDATE y DELETE— para que la curva de aprendizaje sea corta, pero por debajo el modelo es otro: no hay combinaciones, no hay subconsultas y la consulta tiene que poder resolverse con la clave de partición, porque de lo contrario obligaría a recorrer el clúster entero. Ese parecido engañoso es justo lo que conviene tener presente: que se escriba como SQL no significa que se comporte como SQL.
9.4. Cypher y SPARQL, los de los grafos
Cypher es el lenguaje de Neo4j, y su gracia es que se dibuja: los nodos se escriben entre paréntesis y las relaciones con flechas, de modo que el patrón que se busca se parece al grafo que se quiere encontrar. Recorrer una relación cuesta lo mismo sea cual sea la profundidad, algo que en el modelo relacional exigiría encadenar reuniones.
SPARQL consulta grafos RDF de la web semántica, formados por tripletas de sujeto, predicado y objeto, y también está normalizado por el W3C. Y la propia norma SQL ha entrado en este terreno con su parte más reciente, la de grafos de propiedades, que permite escribir consultas de grafo desde el propio SQL.
9.5. Los demás
- MongoDB no tiene un lenguaje textual propiamente dicho: se consulta con documentos que describen el filtro, y su marco de agregación encadena etapas como una tubería.
- MDX consulta cubos multidimensionales de análisis, con sus ejes y sus jerarquías.
- GraphQL, ya dicho, consulta una interfaz de programación y no una base de datos: el cliente pide exactamente los campos que necesita y el servidor devuelve solo esos.
10. Cómo llega la consulta al gestor
Entre la aplicación y la base de datos hay siempre una capa de conectividad, y el tribunal la ha preguntado por sus siglas y por sus paquetes:
| Interfaz | Qué es |
|---|---|
| ODBC | Interfaz en C independiente del gestor, basada en la parte 3 de la norma, con un gestor de controladores que despacha a cada producto. |
| JDBC | El equivalente en Java, con cuatro tipos de controlador: puente sobre otra tecnología, biblioteca nativa del cliente, protocolo de red con intermediario y protocolo nativo escrito enteramente en Java, que es el que se usa hoy. |
| ADO.NET | El componente de la plataforma .NET para comunicación con bases de datos. Cayó con esa definición exacta en 2023. |
🚨 Y una pregunta de 2023 que parece de detalle y no lo es: en una aplicación Java, los paquetes que hacen falta para obtener la conexión desde un origen de datos configurado en el servidor son javax.naming —el servicio de nombres, para localizarlo— y javax.sql —donde vive el origen de datos—. El distractor inventaba un paquete llamado «java.database», que no existe.
Por encima de todo esto, muchas aplicaciones no escriben SQL a mano sino que usan un mapeador objeto-relacional, que traduce entre clases y tablas. En Java la especificación estándar es Jakarta Persistence, con su propio lenguaje de consulta orientado a objetos, JPQL. 🚨 De ella cayó en los dos modelos de 2024 la afirmación correcta: «normalmente, una entidad representa una tabla y cada instancia de la entidad corresponde a una fila de esa tabla». Las falsas decían que no necesita un proveedor que la implemente —sí lo necesita, porque es una especificación y no una implementación—, que su lenguaje se llama «JPSQL» —se llama JPQL— y que no permite relaciones de uno a muchos —sí las permite, junto a las de uno a uno y muchos a muchos—.
10.1. Que la consulta sea correcta no basta: tiene que ser rápida
El último eslabón es la optimización, y conviene cerrar el tema con las tres palancas que un técnico auxiliar usa de verdad:
- Leer el plan de ejecución. Todos los gestores lo muestran, y ahí se ve si la consulta está recorriendo la tabla entera o usando un índice.
- Índices en las columnas del WHERE y de las combinaciones, no en todas: cada índice de más penaliza cada escritura.
- Estadísticas al día, porque el optimizador decide con ellas y con estadísticas viejas elige mal sin que nada haya cambiado en el código.
Y tres antipatrones que aparecen una y otra vez en el código real: aplicar una función sobre la columna en el WHERE, que anula el índice; usar SELECT * cuando solo hacen falta tres columnas, que impide que un índice cubridor resuelva la consulta; y resolver fila a fila con un cursor lo que una sola sentencia haría en conjunto.
10.1. La sentencia preparada
🚨 Sobre esa capa de conectividad el tribunal preguntó por una interfaz concreta y por lo que hace: PreparedStatement, la sentencia preparada de JDBC. La respuesta oficial es que sirve para ejecutar muchas veces una sentencia SQL, y conviene entender por qué eso es una ventaja y no una obviedad.
Hay dos formas de mandar una consulta desde un programa:
- La sentencia normal lleva el SQL ya montado como una cadena de texto. El gestor la recibe entera, la analiza, decide un plan de ejecución y la ejecuta. Si la misma consulta se lanza mil veces con distinto valor, el gestor hace ese trabajo mil veces, porque cada texto es distinto.
- La sentencia preparada se manda una vez con huecos en lugar de valores —marcados con interrogaciones— y el gestor la analiza y planifica una sola vez. Después se rellenan los huecos y se ejecuta cuantas veces haga falta. Eso es exactamente lo que dice la respuesta correcta.
PreparedStatement ps = conexion.prepareStatement(
"SELECT nombre FROM alumno WHERE apellido1 = ?");
ps.setString(1, apellidoBuscado);
ResultSet rs = ps.executeQuery();
Y la segunda ventaja es la que de verdad importa en una Administración, aunque la pregunta no la mencionara: es la defensa canónica contra la inyección de SQL. El valor que se pone en el hueco viaja como dato, separado de la sentencia, así que el gestor nunca lo interpreta como código; da igual que el usuario escriba una comilla y un OR: se buscará literalmente a un alumno con ese apellido absurdo y no se ejecutará nada. Concatenar el valor dentro del texto de la consulta es justo el error contrario, y es el que produce la vulnerabilidad.
Los nombres cambian de plataforma pero la idea es la misma: en .NET la pieza equivalente es la orden con parámetros de ADO.NET, y en los procedimientos almacenados el efecto se consigue de fábrica, porque el cuerpo del procedimiento ya está compilado y lo que se le pasa son argumentos. Esa es, por cierto, la conexión con el apartado 6: un procedimiento almacenado es la forma más completa de conseguir lo mismo, y por eso las dos respuestas suelen convivir en el mismo examen.
11. Cuadros para memorizar
11.1. A qué sublenguaje pertenece cada sentencia
| Sublenguaje | Sentencias | La trampa |
|---|---|---|
| DDL | CREATE, ALTER, DROP, TRUNCATE, RENAME | TRUNCATE está aquí, no en DML |
| DML | INSERT, UPDATE, DELETE, MERGE y SELECT | SELECT es DML para este tribunal |
| DCL | GRANT, REVOKE y DENY | DENY es de Transact-SQL y es DCL |
| TCL | COMMIT, ROLLBACK, SAVEPOINT, SET TRANSACTION | ROLLBACK deshace; SAVEPOINT solo marca |
11.2. Las cinco sentencias que el tribunal pone literales
| Lo que se pide | La forma correcta | El error que ponen al lado |
|---|---|---|
| Impedir duplicados y buscar rápido | ALTER TABLE t ADD CONSTRAINT c UNIQUE (col) | CREATE INDEX, que acelera pero no impide |
| Los alumnos que tienen matrículas | INNER JOIN … ON … | FROM a, b sin condición: producto cartesiano |
| Total por programa | SELECT col, COUNT(*) … GROUP BY col | GROUP sin BY, o SUM(*), que no existe |
| Los diez últimos usuarios | SELECT TOP(10) … ORDER BY fecha DESC | ORDER BY ascendente, o sin ORDER BY |
| Crear un disparador | CREATE TRIGGER n BEFORE UPDATE ON tabla | ON TABLE, OF TABLE, CREATE NEW TRIGGER |
11.3. Las definiciones que caen literales
| Concepto | La frase que el tribunal da por buena |
|---|---|
| ROLLBACK | Restituye todas las modificaciones desde el inicio de la transacción o desde un punto de retorno |
| DROP | Elimina la estructura de una tabla junto con cualquier dato almacenado en ella |
| Disparador | Procedimiento que se ejecuta cada vez que ocurre un evento determinado sobre una tabla determinada |
| Error en un trigger | SÍ cancela automáticamente la operación que lo disparó |
| Evento de ejecución única | SE ELIMINA SOLO al terminar, salvo declaración en contra |
| PL/SQL | Lenguaje de procedimiento que admite sentencias SQL y se almacena compilado en la base de datos |
| OQL | Un lenguaje de consulta de datos |
| Sentencia preparada | Permite ejecutar muchas veces una sentencia SQL |
| Machine Learning Services | Ejecutar scripts de Python y R con datos relacionales |
| ADO.NET | Componente de .NET para la comunicación con bases de datos |
11.4. Los números y las listas cerradas
| Dato | Valor |
|---|---|
| Norma de SQL | ISO/IEC 9075, novena edición SQL:2023; once partes activas |
| La parte del lenguaje · la de los procedimientos | 2 (Foundation) · 4 (PSM) |
| Niveles de aislamiento | No confirmada, confirmada, repetible y serializable |
| La repetible | Evita sucia y no repetible; admite fantasma |
| Anomalías de concurrencia | Sucia, no repetible y fantasma (no existe la «hundida») |
| Eventos que activan un trigger | INSERT, UPDATE y DELETE |
| Momentos de un trigger | BEFORE, AFTER e INSTEAD OF (sobre vistas) |
| Tipos de trigger en SQL Server | DML, DDL y LOGON |
| Tipos de procedimiento en SQL Server | Definidos por el usuario, temporales, de sistema y extendidos |
| Cypher · CQL · OQL | Neo4j · Cassandra · bases de datos de objetos |
| INSTR('Corporate Floor','or',3,2) | 14 |
| Puerto de SQL Server · MySQL | TCP 1433 · TCP 3306 |
11.5. Las cuatro parejas que el tribunal intercambia
- DELETE / DROP: uno borra filas y admite condición; el otro se lleva el objeto entero.
- ROLLBACK / SAVEPOINT: uno deshace; el otro solo marca hasta dónde se podrá deshacer.
- WHERE / HAVING: uno filtra filas antes de agrupar; el otro filtra grupos después.
- COUNT(*) / COUNT(columna): el primero cuenta filas con nulos incluidos; el segundo, solo los valores presentes.
12. Lo que ya ha preguntado el tribunal
Las preguntas reales de exámenes oficiales del INAP que se responden con este tema, agrupadas por lo que hay que saber. Si con el apunte leído contestas esta lista, el tema está hecho.
| Lo preguntado | Veces | La respuesta |
|---|---|---|
| Base de datos que usa Cypher | 2 | Neo4j |
| A qué sublenguaje pertenece DENY | 2 | DCL |
| Restituir las modificaciones desde el inicio o desde un punto de retorno | 2 | ROLLBACK |
| Forma válida de comenzar un trigger en ANSI SQL | 3 | CREATE TRIGGER n BEFORE UPDATE ON tabla |
| Señale la INCORRECTA sobre disparadores | 3 | La falsa: que el error no cancela la operación |
| Impedir DNI duplicado con máximo rendimiento | 2 | ALTER TABLE … ADD CONSTRAINT … UNIQUE |
| Alumnos que tienen matrículas | 2 | INNER JOIN … ON … |
| Total de matrículas por programa | 2 | SELECT col, COUNT(*) … GROUP BY col |
| Crear usuario en Oracle | 2 | CREATE USER … IDENTIFIED BY … |
| El comando SELECT, ¿qué es? | 2 | Un comando DML |
| Referente al comando DROP | 2 | Elimina la estructura junto con los datos |
| Señale la INCORRECTA sobre sentencias SQL | 1 | La falsa: que DELETE borra objetos |
| Eliminar los datos pero no la definición | 1 | DELETE |
| Qué es OQL | 2 | Un lenguaje de consulta de datos |
| Niveles de aislamiento: la sentencia correcta | 1 | La repetible admite fantasmas |
| Tipos de trigger en SQL Server | 1 | DML, DDL y LOGON |
| Tipos de procedimiento almacenado en SQL Server | 1 | Usuario, temporales, de sistema y extendidos |
| Crear una vista con recuento por usuario | 1 | CREATE VIEW … COUNT(…) … GROUP BY … |
| Los diez últimos usuarios en SQL Server | 1 | TOP(10) … ORDER BY fecha DESC |
| Reiniciar la identidad de una tabla | 1 | DBCC CHECKIDENT |
| INSTR con posición y ocurrencia | 1 | 14 |
| Insertar un registro con cadenas | 3 | INSERT INTO … VALUES ('TAI', '…'); con las comillas cerradas |
| Crear una tabla con columna de 2.000 caracteres | 2 | CREATE TABLE … varchar(2000) |
| Crear tabla con clave autonumérica en MySQL | 3 | … PRIMARY KEY AUTO_INCREMENT … |
| Ficheros adjuntos que no son PDF | 2 | NOT LIKE '%.pdf' con la subconsulta completa |
| Usuarios y máquina desde la que acceden | 3 | SELECT user, host FROM mysql.user |
| Cláusula del criterio de ordenación | 1 | ORDER BY |
| Lenguaje de procedimiento de Oracle | 2 | PL/SQL |
| Punto de recuperación dentro de una transacción | 1 | SAVEPOINT |
| Finalidad de una sentencia preparada | 1 | Ejecutar muchas veces una sentencia SQL |
| Condicional dentro de un SELECT | 1 | CASE … WHEN … THEN … END |
| Señale la INCORRECTA sobre eventos | 1 | La falsa: que hay que eliminarlo manualmente |
| Qué es Machine Learning Services | 1 | Ejecutar Python y R con datos relacionales |
| Paquetes Java para conectar a la base | 1 | javax.naming y javax.sql |
| Sobre Jakarta Persistence | 2 | Una entidad es una tabla; cada instancia, una fila |
| Puerto del motor de SQL Server | 1 | TCP 1433 |
Cómo estudiar este tema, en cuatro reglas. Primera: escribe las sentencias. Este tribunal no pregunta qué es una combinación, pregunta cuál de las cuatro está bien escrita, y esa diferencia solo se cubre habiendo tecleado la consulta. Segunda: memoriza las listas cerradas —los eventos de un disparador, los tipos de procedimiento de SQL Server, los cuatro niveles de aislamiento—, porque el distractor siempre cambia una sola palabra de la lista buena. Tercera: vigila las palabras pequeñas, que es donde está la trampa: el BY del GROUP BY, el ON del trigger, el DESC del ORDER BY, el NOT del LIKE y las dos comillas de cada cadena. Y cuarta: cuando el enunciado diga «en el estándar ANSI SQL» piensa en la forma normalizada, y cuando diga «en Oracle» o «en SQL Server», en la del dialecto; el tribunal lo especifica siempre, y esa palabra decide la respuesta.
Recuerda además la aritmética del ejercicio: cada error descuenta un tercio de un acierto y los blancos no penalizan. En las preguntas de sintaxis eso juega a favor, porque casi siempre hay dos opciones que son imposibles a simple vista —un verbo inventado, una palabra de más— y descartarlas convierte la pregunta en una moneda al aire con la apuesta a favor.
¿Te lo sabes? 🐂
Cien preguntas de este tema, escritas al estilo del cuestionario del INAP y contrastadas con los nueve exámenes oficiales que tenemos resueltos. Crea tu cuenta gratis para guardar tu progreso y repasar tus falladas. Gratis y siempre lo será.
