You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Las opciones para el comando mysql pueden ser especificadas en el grupo [mysql] de /etc/my.cnf, y sobreescritas en ~/.my.cnf, y también sobreescritas en el fichero que se especifique en la opción --defaults-extra-file
mysql -h funciona solo en Windows, y trata de conectarse al servidor local con shared memory o named pipeline.
Especificando -h 127.0.0.1, la conexión se hace a través de TCP/IP.
SQL Modes:
ANSI QUOTES: dobles comillas en lugar de una.
IGNORE_SPACE: permite espacio entre el nombre de una función y los paréntesis.
ERROR_FOR_DIVISION_BY_ZERO: lanza warning cuando al dividir por cero, o error si está en strict mode.
STRICT_TRANS_TABLES, STRICT_ALL_TABLES: modo estricto (tipos) en los INSERTs (transaccionales o todas).
TRADITIONAL: activa strict mode y algunas restricciones más en los INSERTs.
ANSI: ANSI_QUOTES + operador || como concatenación (en vez de OR), otros.
Respuestas del test:
false ✓
false ✓
true ✗
false ✓
socket, tcp/ip ✓
host ✗ --user (-u) and --password (-p)
local, tcp/ip, no ✗ socket on Unix, tcp/ip on Win
local, tcp/ip, no ✗ shared memory or named pipe, so it works only on Win
local, tcp/ip, no ✓
remote, tcp/ip, no ✗ remote or local if ip is 192.168.10.1
depends on defaults, depends on defaults, no ✗ local, socket on Unix, shared memory/named pipe on Win
Funciones de cadenas: LENGTH(), CHAR_LENGTH(), CONVERT(cadena USING charset), STRCMP(a, b) (devuelve -1, 1 o 0 si a es mayor, menor o igual, según el cotejamiento), CONCAT(a, b), CONCAT_WS(separador, cadenas), ENCODE(), DECODE(), DES_ENCRYP(), DES_DECRYPT(), AES_ENCRYPT(), AES_DECRYPT()
Funciones de NULL: ISNULL(), IFNULL(valor, devuelto)
Comentarios: # para una línea, -- para una línea (espacio obligatorio), /* / para multilínea, /! QUERY / para lanzar la query, /!version QUERY */ para lanzar la query si la versión es >= version
Respuestas del test:
Any type defined as NOT NULL ✗ Table columns (Name, IndepYear), literal values and function (CONCAT, IF)
Float values are not exact. The CPU manages the representation of the values, and the accuracy cannot be guaranteed, so the result of the sum cannot be safely determined as exact. ✓
✗ sql_mode was set to ANSI_QUOTES before the second statement
When executing the first statement, the session_collation specifies a collation that does not match as equals the strings in the variables (for example, any binary collation). In the second, the session_collation specifies a collation that does. ✗ default collation was latin1_swedish_ci, and latin1_german2_ci was set after
true, since the bytes that represents both strings are equal. ✓
SELECT UPPER(CONVERT(@var USING latin1); ✓
The second one is executed with the IGNORE_SPACES mode enabled, whereas in the second it's disabled. ✓ IGNORE_SPACE
✗ Constants can be literal numbers, strings or temporal values. A SQL expression can be constant, NULL, references to table columns or functions.
SELECT 9 = 9; ✓
SELECT 'Hello world' IS NOT NULL; ✓
SELECT '2013-01-01' + INTERVAL 2 DAYS; ✓
✗ SELECT '21:39:00';
SELECT Name FROM world.Country; ✓
SELECT NOW(); ✓
SELECT NOW() = '2013-02-12'; ✓
SELECT pid, salary AS GrossSalary, salary*0.4 AS Deduction, GrossSalary-Deduction AS NetSalary FROM personnel; ✓
SELECT unit, SUM(salary) AS GrossSalary, GrossSalary*0.4 AS Deduction, GrossSalary-Deduction AS NetSalary FROM personnel GROUP BY unit; ✓
SELECT pid, salary AS GrossSalary, salary*IF(GrossSalary >= 2000, 0.4, 0.3) AS Deduction, GrossSalary-Deduction AS NetSalary FROM personnel; ✓
SELECT pid, salary AS GrossSalary, salary*1.1 AS 'Cost Rise' FROM personnel; ✗ salary * .1 AS 'Cost Rise'
SELECT pid, salary AS GrossSalary, salary*IF(unit = 23, 1.1, 1.05) AS 'Cost Rise' FROM personnel; ✗ SUM(salary) * IF(unit = 23, .1, .05) AS 'cost rise'
a) +---------+
| name |
+---------+
| Lennart |
+---------+ ✓
b) 1 ✗ 4
c) 4 ✗ error porque no hay sentencia GROUP BY, obligatoria cuando hay COUNT() y otras columnas NO agregadas
a) 4, b) 4, c) 4 ✗ c) error
LENGTH() returns the length in bytes, CHAR_LENGTH() in characters (different in multi-byte charsets). ✓
false ✓
a) 'FALSE', b) 'FALSE', c) 'FALSE' ✗ a) TRUE, because default collation is case-insensitive
1 ✓
0 ✓
1 ✓
0 ✓
1 ✗ 0
1 ✓
1 ✓
1 ✓
NULL ✓
NULL ✓
1 ✓
0 ✓
1 ✓
0 ✗ 1
0 ✓
SELECT City, Country, Population FROM CityList WHERE Country IN ('DNK', 'DEU', 'USA') AND Population BETWEEN 400000 AND 500000 ORDER BY Population DESC; ✓ Name as City
Error. == is not a valid SQL operator ✓
Error. = is not a ternary operator. ✗ NULL since there is at least one NULL expression
Error. = is not a ternary operator. ✗ NULL since there is at least one NULL expression
INSERT: Si no se especifica una columna, se tomará el default (del campo o del tipo) o error si modo estricto
INSERT: se puede poner lista de columnas vacía, en cuyo caso se rellenarán todos los campos con default
INSERT múltiples están limitados por max_allowed_packet (transferencia), default 1MB
INSERT múltiples: devuelve información Records, Duplicates y Warnings.
INSERT múltiples: si INSERT IGNORE, si no da error al haber duplicados en UNIQUEs. En MyISAM inserción parcial, en InnoDB no se inserta nada si falla algo. ON DUPLICATE KEY col1=value1, [col2=value2, ...] actualiza la fila duplicada y devuelve OK, 2 rows affected
REPLACE INTO tabla SET/VALUES: elimina el duplicado e inserta la nueva. Solo funciona con claves únicas que no admitan NULL
UPDATE no produce efectos si los nuevos valores son idénticos a los antiguos
UPDATE devuelve el número de filas afectadas
UPDATE ... SET ... ORDER BY ... LIMIT limite (ojo, LIMIT no admite offset, solo nº máximo de filas afectadas)
mysql --safe-updates prohibe UPDATEs sin WHERE o LIMIT o que afecten a más de 1000 filas
DELETE devuelve el nº de filas borradas, TRUNCATE no
TRUNCATE reinicia el auto_increment, y DELETE también solo si no tiene WHERE
DELETE ... ORDER BY ... LIMIT limite (igual que UPDATE)
Privilegios: REPLACE necesita los permisos INSERT y DELETE; TRUNCATE necesita el permiso DELETE.
Respuestas del test:
(1, '', '', '', '0') <- 1 because AUTO_INCREMENT ✓
It will fail, because with strict_mode you cannot enter NULL values in NOT NULL columns ✓
a) INSERT INTO twounique VALUES (1, 1) ✓
b) INSERT IGNORE INTO twounique VALUES (1, 1), (2, 3) ✗ use REPLACE instead
c) REPLACE INTO twounique VALUES (1, 1) ✓
d) INSERT INTO twounique VALUES (1, 2) ON DUPLICATE KEY UPDATE id1=2, id2=3 ✓
Obtiene filas que coinciden entre dos tablas. Dos formas equivalentes:
... FROM t1, t2 WHERE ... si no se especifica WHERE, producto cartesiano. Se puede prohibir con --safe-updates
INNER JOIN
LEFT JOIN
Produce un resultado por cada fila de la tabla de la izquierda. Si no coincide con la tabla de la derecha aparece NULL..
Respuestas del test:
Inner join ✗ any join can do it
LEFT JOIN with a WHERE field IS NULL condition ✗ Outer JOINs = RIGHT and LEFT joins
SELECT Country.Name, Language
FROM Country, CountryLanguage
WHERE Country.Code = CountryLanguage.CountryCode
AND IsOfficial = 'T'
ORDER BY Country.Code; ✓
USING Is not possible bc the matching field does not have the same name in both tables. SQL:
SELECT Country.Name, Language
FROM Country
INNER JOIN CountryLanguage ON Country.Code = CountryLanguage.CountryCode AND IsOfficial = 'T'
ORDER BY Country.Code; ✓
SELECT Country.Name, City.Name, City.Population
FROM City
INNER JOIN Country ON City.CountryCode = Country.Code AND Country.IndepYear IS NULL; ✓
SELECT Country.Name, SUM(City.Population)
FROM Country
JOIN City ON City.CountryCode = Country.Code
WHERE Country.IndepYear IS NULL
GROUP BY Country.Code; ✓
SELECT ... FROM City RIGHT JOIN Country.
It returns a lot of results, does a full scan and takes much resources. Also, it is rarely useful.
We specify some condition in the JOIN to reduce the results fetched by the SELECT.
✗ You can get a cartesian product with a FROM with comma operator and no WHERE statements. You can avoid them with --safe-updates
✗ It's always possible if there are only 2 tables
When fields with the same name are in two or more JOINed tables. It's also useful for the SQL readibility. ✓
When you are JOINing two tables with the same name in different databases. ✓
✗ With self-joins.
3, 4, 5 ✗ JOINs work for INSERT, UPDATE and DELETE. It IS possible to change data in more than 1 table when joining tables in UPDATE or DELETE
SELECT cp.Name 'Country', Country.Name 'Other countries', Country.Continent, Country.SurfaceArea
FROM Country
JOIN Country cp ON Country.SurfaceArea > cp.SurfaceArea AND cp.Name = 'Paraguay' AND Country.Continent = cp.Continent; ✓
SELECT cp.Name 'Country', Country.Name 'Other countries', Country.Population
FROM Country
JOIN Country cp ON Country.Population >= cp.Population AND cp.Name = 'Germany'
ORDER BY Country.Population DESC;✓
SELECT cp.Name 'Country', Country.Name 'Other countries', SUBSTRING(Country.Region, 1, 10) Region, Country.Population, Country.SurfaceArea
FROM Country
JOIN Country cp ON Country.Population >= cp.Population AND Country.SurfaceArea >= cp.SurfaceArea AND cp.Name = 'Nepal'
ORDER BY Country.Population DESC; ✗ WHERE Country.region = cp.region
5*8 = 40, 8 ✓
6, 4 ✓
SELECT client.name CLIENT, '' PROJECT, '' START, '' END FROM client LEFT JOIN project USING (cid) WHERE pid IS NULL; ✗ col vacías => NULL
SELECT client.name CLIENT, project.name PROJECT, project.start START, project.end END
FROM client
JOIN project ON client.cid = project.cid AND YEAR(start) = 2003
ORDER BY start ✓
SELECT client.name CLIENT, project.name PROJECT, project.start START, project.end END
FROM client
LEFT JOIN project ON client.cid = project.cid
WHERE project.name = 'Intranet' ✓
SELECT client.name CLIENT, project.name PROJECT, project.start START, project.end END
FROM client
INNER JOIN project ON client.cid = project.cid
AND project.name = 'Intranet' ✓
SELECT client.name CLIENT, project.name PROJECT, project.start START, project.end END
FROM client
INNER JOIN project USING (cid)
WHERE project.name = 'Intranet' ✓
SELECT client.name CLIENT, project.name PROJECT, project.start START, project.end END
FROM client
JOIN project USING (cid)
ORDER BY client.name, project.start ✗ LEFT JOIN
Se pueden usar subqueries en INSERT, UPDATE, DELETE, CREATE TABLE...SELECT, etc pero NO se puede hacer subquery sobre la tabla que está siendo modificada.
Respuestas del test:
In any place where a scalar is expected: SELECT here FROM here WHERE here, UPDATE ... SET field = here... NOT in LIMIT statements ✓
It's not, because the subquery can be performed independently from the outer. ✓
SELECT * FROM Country c WHERE Continent = 'South America' AND Population = (SELECT MIN(Population) FROM Country WHERE Continent = c.Continent); ✓
The Continent and Name of the country with the greatest population of each continent ✓
The Continent and Name of the countries whose SurfaceArea is greater than the average surface area of their countries.✗ of any country
SELECT * FROM Country WHERE SurfaceArea > ALL (SELECT SurfaceArea FROM Country GROUP BY Continent)
SELECT DISTINCT Language
FROM CountryLanguage
WHERE CountryCode IN (SELECT Code FROM Country WHERE GovernmentForm LIKE 'Monarchy%') ORDER BY Language; ✓
SELECT Name
FROM Country c
WHERE EXISTS (SELECT CountryCode FROM CountryLanguage WHERE Language = 'German' AND CountryCode = c.Code) ✓
SELECT Population
FROM City
WHERE (Name, District, CountryCode) = ('Houston', 'Texas', 'USA'); ✓
SELECT SUM(cl.Percentage * Population * .01)
FROM (SELECT CountryCode, Percentage FROM CountryLanguage WHERE Language = 'German') cl, Country
WHERE Country.Code = cl.CountryCode AND Country.Region = 'Western Europe'; ✓
Because it uses a field FROM a table of the outer query. ✓
? raro raro raro lo que está pasando con MySQL.
SELECT pid Project ID, project.name Project Name, id Client No, client.name Client Name FROM client LEFT JOIN project USING (id) ✗ project LEFT JOIN client WHERE client.name IS NOT NULL
SELECT pid Project ID, project.name Project Name, id Client No, client.name Client Name FROM client RIGHT JOIN project USING (id) ✗ ...WHERE client.name IS NOT NULL
SELECT pid Project ID, project.name Project Name, id Client No, client.name Client Name FROM client INNER JOIN project USING (id) ✗ project INNER JOIN client
SELECT pid Project ID, project.name Project Name, id Client No, client.name Client Name FROM project LEFT JOIN client USING (id) WHERE client.id IS NULL ✓
SELECT pid Project ID, project.name Project Name, id Client No, client.name Client Name FROM client LEFT JOIN project USING (id) WHERE client.id IS NULL ✗ RIGHT
En vez de CREATE [OR REPLACE] se puede usar ALTER TABLE
Especificar explícitamente las columnas es útil para cuando hay nombres repetidos en el select_statement o este contiene funciones.
Algoritmos
MERGED: cuando se hace un SELECT sobre la view, MySQL mezclará las cláusulas del SELECT con las cláusulas del SELECT que define la view, y ejecutará la query sobre la tabla base.
TEMPTABLE: cuando se hace un SELECT sobre la view, MySQL guardará el resultado de la view en una tabla temporal, y posteriormente, ejecutará el SELECT sobre esta tabla temporal. Puede ser interesante usar TEMPTABLE para minimizar el bloqueo de tablas, ya que cuando se lanza un SELECT, la tabla base solo estará bloqueada hasta que haya sido volcada a la tabla temporal, mientras que con MERGED estará bloqueada hasta que toda la query haya sido procesada.
UNDEFINED: selección automática. Intentará elegir MERGED primero ya que es más eficiente.
UPDATEABILIDAD de las tablas
Cada fila de la vista debe corresponder a una fila de la tabla (por tanto, no agregación)
Las columnas deben ser definidas como referencias, no pudiendo contener ningún cálculo ni función
Para INSERTs, además, las columnas que no estén en la vista deben tener un valor DEFAULT
WITH CHECK OPTION
Los datos introducidos en INSERTs y UPDATEs deben cumplir las condiciones del select_statement, es decir, deben estar dentro de la vista
Si la vista está definida en base a otra(s) vista(s)...
WITH CASCADED CHECK OPTION (=WITH CHECK OPTION): hace esta comprobación en todas las vistas
WITH LOCAL OPTION: hace esta comprobación solo con las condiciones de la vista de primer nivel.
OTRAS COSAS
ALTER TABLE new_definition
DROP VIEW [IF EXISTS] vista [,vista2, ...]
SHOW CREATE TABLE, SHOW TABLE STATUS, SHOW FULL TABLES, SHOW COLUMNS y DESCRIBE funcionan con vistas, así como SHOW CREATE VIEW
Permisos: CREATE VIEW, DROP, SHOW VIEW si no se tiene permisos de SELECT sobre la tabla base
Respuestas del test:
It can fullfill all the requirements of the updatable views but if the base table does not have a default value for all the fields that are not in the view definition, it can't be insertable ✗ if it has columns as expressions, it can also be updatable but not insertable
updatable and insertable ✓ but UPDATEs and INSERTs can only affect to one table
CREATE VIEW continents AS SELECT Continent, SUM(SurfaceArea), AVG(SurfaceArea) FROM Country GROUP BY Continent. It's not updatable because it contains aggregate data. ✓
✗ Summary tables has the advantage of performance, because it stores the table results when created (views have to query it each time), but data became obsolete (since data is not updated from base table automatically), where views always get latest data from table.
MySQL raises a warning and the UNDEFINED algorithm is chosen instead of it. ✓
a) view, b) table ✗ only view
a) Include a column list, b) Provide column aliases in the view SELECT statement ✓
a) ALGORITHM=TEMPTABLE, c) Use of aggregate functions, d) Use of GROUP BY or HAVING clauses in the view definition, e) Use of expressions like col = col + 1 in the view definition ✗ e) It depends on columns being updated
Only for updatable views ✓
Because TEMPTABLE creates non updatable views, and WITH CHECK OPTION is for updatable views only ✓
LOAD DATA [LOCAL] INFILE ‘file_name’ [IGNORE | REPLACE]
INTO TABLE table_name [format_specifiers]
[IGNORE n LINES] [(column_list)]
[SET (assignment_list)]
Inserta registros en la tabla indicada a partir de un fichero TSV.
LOAD DATA INFILE: fichero en servidor. La ruta del fichero se calcula a partir del directorio de la BD activa.
LOAD DATA LOCAL INFILE: fichero en cliente. La ruta del fichero se calcula a partir del directorio en que fue lanzado el cliente mysql.
IGNORE n LINES ignora las n primeras filas del TSV
Si el TSV tiene más columnas que la tabla, se omiten. Si tiene menos, se inserta el DEFAULT.
Se pueden especificar las columnas en las que se insertarán los datos del TSV en column_list
Duplicados: por defecto (inserta las filas correctamente hasta que se produce el duplicado), IGNORE (inserta todas las filas que no produzcan duplicado) y REPLACE (inserta todas las filas, reemplazando las que producen duplicado). En ficheros locales, IGNORE es el modo por defecto.
Para ficheros en servidor es necesario el permiso FILE
SELECT INTO OUTFILE
SELECT * INTO OUTFILE ‘file’ [format_specifiers]
FROM mi_tabla ...;
Escribe fichero TSV en servidor, con propietario mysql y permisos de lectura para todos
El fichero no puede existir previamente
format_specifiers
FIELDS
TERMINATED BY 'char'
[OPTIONALLY] ENCLOSED BY 'char'
ESCAPED BY 'char'
LINES TERMINATED BY 'string'
Options son las mismas opciones de format_specifiers más LOCAL e IGNORE: --fields-terminated-by, --fields-escaped-by, --fields-enclosed-by, --lines-terminated-by, --local, --ignore
mysqldump
Con --tab=dir se guarda un TSV en dir con los contenidos de la tabla, y un SQL con el DDL, pero ¡OJO! el TSV se guarda en el servidor y el SQL en el cliente.
Con --no-create-info se omite el fichero
La cuenta debe tener permiso FILE para escribir ficheros en servidor
--databases y --all-databases no puede ser usado con --tab ya que solo se puede guardar 1 BD en TSV
Se pueden usar los mismos format_specifiers que mysqlimport
Respuestas del test:
0, N, NULL; \N \N \N ½ 0, N, 0000-00-00
'C:\Dokumente und Einstellungen\All Users\data for t.txt' ✓
a) LOAD DATA INFILE 'more_contries.dat' INTO TABLE Country (Code, Name); b) Yes, because all the fields have a DEFAULT value. ✓
FILE, SELECT, INSERT and UPDATE/REPLACE if REPLACE mode is selected ✗ FILE and access permissions to the file in the server
mysqlimport ✓
Tabs and \n ✓
When file is in server, default is stop and raise an error when a duplicated is found. When file is in client, IGNORE is the default behavior. ✓
? ✗ there were 9 records in the file, and the 9 produced a duplicated resolved with REPLACE, and so there are 18 affected. Also, there were 2 problems importing the file.
? ✗ 9 lines in the file, and 9 caused a duplicated resolved by skipping them => 0 affected. Also, there were 2 problems.
mysqlimport and mysql ½ mysql with LOAD DATA INFILE
For multiple databases, tab format can't be used. We can use --databases or --all-databases option to export them in SQL format. ✓
mysqldump --databases=a,b,c tbl1 tbl2 ✓
LOAD DATA INFILE 'even_more_countries.dat' (Code, Name, @PopCity, @PopRural) INTO TABLE Country IGNORE 1 LINES (@skip, Code, Name, @PopCity + @PopRural)
✗ LOAD DATA INFILE 'even_more_countries.dat' INTO TABLE Country IGNORE 1 LINES (@unused, Code, Name, @PopCity, @PopRural) SET Population = @PopCity + @PopRural
The directory of the active database ✓
Every column ✓
0 ✓
SELECT pid, unit INTO OUTFILE 'filename' FIELDS ENCLOSED BY '"' TERMINATED BY ';' LINES TERMINATED BY '\r\n' FROM personnel ORDER BY grade LIMIT 5
Because if you need to execute a statement a number of times just changing paremeters, with prepared you save to parse, compile and process the parts of the statement that don't depend on parameters. ✓
2 ✗ 1
Nothing. Prepared statements are per-session. ✓
PREPARE s1 FROM 'SELECT Name FROM Country WHERE Continent = ? AND Population > ?';
SET @continent = 'Asia';
SET @pop = 100000000;
EXECUTE s1 USING @continent, @pop; ✓
Error. Prepared statement does not exist. ✓
DEALLOCATE PREPARE stmt; DROP PREPARE stmt; No, it's removed when session is disconnected. ✓
Al contrario que funciones, no hay valor retornado y se pueden usar parámetros de salida, además de entrada
delimiter //
CREATE PROCEDURE my_procedure (parameters)
[characteristics]
BEGIN
SELECT ...;
END
//
CREATE FUNCTION my_func (parameters)
RETURNS data_type
[characteristics]
BEGIN
...
RETURN ...
END
//
El delimiter puede ser cualquiera distinto al delimiter por defecto (;)
characteristics := SQL SECURITY {DEFINER|INVOKER} Indica si la rutina se ejecutará con los permisos del usuario que la definió o los del que la invocó
{DETERMINISTIC|NO DETERMINISTIC} Indica si es determinística o no
LANGUAGE SQL Indica que la rutina está escrita en SQL. Impresionante.
COMMENT 'comentario'
Tras la ejecución de una rutina, el sql mode es el que había cuando la rutina fue definida. De regalo.
BLOQUES
Los scopes se heredan en bloques anidados.
...
bloque: BEGIN
...
LEAVE inner_block; # Sale del bloque indicado
END inner_block;
...
La clásula [IN|OUT|INOUT] solo se aplica a procedures. Un parámetro de salida es aquel que puede ser accedido por el invocador. Si es OUT, inicialmente valdrá NULL y no se tendrá en cuenta en la invocación de la rutina.
DECLARE
Variables
DECLARE var1, var2, ... DATATYPE [DEFAULT value]
Declara variables y condiciones, cursors y handlers, en ese orden
Los nombres son únicos por tipo
NO se usa el prefijo @ en las variables
Handlers
DECLARE [CONTINUE|EXIT|UNDO] HANDLER FOR condition_type [, condition_type2] stmt;
La condition_type puede ser declarada previamente con:
DECLARE condition_name CONDITION FOR condition_type
...donde condition_type := SQLSTATE 'num' | otra condition | SQLWARNING | NOT FOUND | SQLEXCEPTION
Por ejemplo,
DECLARE null_no_permitido CONDITION FOR SQLSTATE '23000';
DECLARE CONTINUE HANDLER FOR null_no_permitido SET salir = 1;
Cursores
DECLARE nombre CURSOR FOR SELECT ...;
Los cursores operan sobre la query declarada, para lo cual primero se abre con OPEN y luego se accede a sus filas con FETCH
OPEN nombre
BEGIN
DECLARE EXIT HANDLER FOR SQLSTATE '02000' BEGIN END
LOOP
FETCH nombre INTO variable1, variable2
...
END LOOP
END
Condicionales
IF expr
THEN
[ELSE IF expr THEN ...]
[ELSE ...]
END IF;
CASE expr
WHEN val THEN ...
WHEN val THEN ...
[ELSE ...]
END CASE;
CASE
WHEN expr THEN ...
WHEN expr THEN ...
[ELSE ...]
END CASE;
Iteradores
Bucle infinito (necesita instrucción explícita de salida):
[label:] LOOP
...
LEAVE label;
END LOOP [label];
Bucle con condición al final:
[label:] REPEAT
...
UNTIL expr
END REPEAT [label];
Bucle con condición al principio:
[label:] WHILE expr DO
...
END WHILE [label:];
ITERATE label transfiere el control solo en iteradores
ALTER y DROP
Solo se pueden modificar las characteristics de un procedimiento o función:
ALTER PROCEDURE procedimiento [characteristics];
ALTER FUNCTION funcion [characteristics];
Para modificar otros aspectos (parámetros, cuerpo...) hay que eliminar y crear de nuevo la rutina.
DROP PROCEDURE [IF EXISTS] nombre;
DROP FUNCTION [IF EXISTS] nombre;
INVOCACIONES
Procedimiento: nunca desde una expresión. Siempre con CALL nombre();
Función: siempre desde una expresión: SELECT function();
Info y permisos
INFORMATION_SCHEMA.ROUTINES
SHOW PROCEDURE STATUS, SHOW FUNCTION STATUS
SHOW CREATE PROCEDURE, SHOW CREATE FUNCTION
Permisos:
CREATE ROUTINE
EXECUTE
ALTER ROUTINE
La cláusula ON puede ser usada sobre rutinas
Respuestas del test:
Reuse code, traffic savings, more security, cleaner calls ½ more flexible syntax than "regular" SQL; exception handling
Stored procedure ✓
CREATE PROCEDURE world.world_before_count(); ✓
Specifying the characteristic SQL SECURITY INVOKER ✓
1 true, 2 true, 3 only if SQL SECURITY DEFINER characteristic is declared ✓
2 and 3 ✗ only 2
Nope, they cause a duplicate ✓
Yes, since they are different type of DECLAREs ✓
No, read only ✓
DECLARE IGNORE name HANDLER FOR exception_type ...; ✗ CONTINUE with an empty block (BEGIN END)
LOOP, REPEAT, WHILE ✓
REPEAT ✓
WHILE ✓
The inner block ✗ the outer one, because it's the block in which the handler was defined
SHOW CREATE PROCEDURE world.world_record_count ½ also in INFORMATION_SCHEMA.ROUTINES
SQL SECURITY and COMMENT ✓
d) Infinite loop, because is NULL, and NULL + 1 = NULL => it never reaches the exit condition ✓
\G es un terminador pero también hace que los resultados se muestren horizontalmente.
El prompt estándar es mysql>. -> espera la siguiente línea de la sentencia, y '>, "> ``>y/*>` esperan cierres de los símbolos correspondientes.
Cargar un batch: SOURCE fichero (sin comillas) o desde la shell, mysql < fichero.
Cuando se carga un batch, un error detendrá el procesamiento. Para seguir a pesar de errores, mysql -f.
Los batches pueden contener sentencias SOURCE, pero cuidado con las referencias circulares.
Los batches imprimen la salida en tablas separadas por tabuladores, no como en el modo interactivo.
-B fuerza salida con tabuladores, -t en forma de tabla (como en el modo interactivo), -H en HTML y -X en XML
Comandos propios del mysql interactivo: CLEAR, EXIT, SOURCE, STATUS, HELP. No se pueden usar en sentencias de varias líneas a no ser que se invoque mysql --named-commands.
--i-am-a-dummy es sinónimo de --safe-updates, el cual evita SELECTs de más de 1000 filas y de más de 1M de filas examinadas en los SELECT de múltiples tablas, así como UPDATEs o DELETEs en los que no se identifique los registros a alterar, o no incluyan LIMIT.
Respuestas del test:
mysql -h db.myexample.com -u juan -p -D world < /tmp/queries.sql ✓
\G ✓
');, \c ✗ '\c hay que cerrar las comillas simples
USE test; SOURCE /tmp/tbl_import.sql;, mysql -D test < /tmp/tbl_import.sql, USE test; SOURCE /tmp/tbl_import.sql; ✗ el último es mysql --force test < /tmp/tbl_import.sql
En DATABASES, TABLES y COLUMNS puede usarse LIKE 'patron'
mysqlshow
CLI para SHOW
mysqlshow [options] [database] [tabla] [columna]
Si no se especifica un objeto, se describirá el de nivel superior.
Especificando una tabla y la opción --keys, se muestran los índices de la tabla
Si el nombre de la BD, tabla o columna es un patrón entrecomillado, se interpretará como LIKE
Respuestas del test:
mysqlshow test 'my%' ✓
mysqlshow --keys test mytable. No. ✓
mysqlshow --keys buildings, mysql -c "DESC buildings" ✓
mysqlshow 'w%'; SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME LIKE 'w%'; ✓
mysqlshow world; SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLE WHERE TABLE_NAME; ✗ WHERE TABLE_SCHEMA = 'world'
mysqlshow world 'C%'; SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'world' AND TABLE_NAME LIKE 'C%'; ✓
mysqlshow world City; SELECT COLUMN_NAME FROM COLUMNS WHERE TABLE_NAME = 'City' AND TABLE_SCHEMA = 'world'; ✓
mysqlshow --keys world City; SELECT KEY_NAME FROM KEYS WHERE TABLE_NAME = 'City' AND SCHEMA_NAME = 'world'; ✗ FROM KEY_COLUMN_USAGE WEHERE TABLE_SCHEMA = 'world' AND TABLE_NAME = 'City'
SHOW CHARACTER SET ✗ SELECT * FROM INFORMATION_SCHEMA.CHARACTER_SETS
SELECT * FROM INFORMATION_SCHEMA.CHARACTER_SET_COLLATION_APPLICABILITY; ✓
SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'INFORMATION_SCHEMA'; ✓
TIMESTAMP (4) 1-1-1970 0:0:0 - 2037, DEFAULT CURRENT_TIMESTAMP, ON UPDATE CURRENT_TIMESTAMP, por defecto ambos atributos están activos en el primer campo TIMESTAMP de la tabla. ¡Ojo! No puede haber más de un campo con CURRENT_TIMESTAMP. Si un campo TIMESTAMP tiene DEFAULT 0, al hacer un INSERT con NULL, en vez de NULL se insertará al fecha/hora actual, así que es una forma de saltarse la restricción de 1 solo campo con CURRENT_TIMESTAMP por tabla. Si un campo TIMESTAMP permite NULL, su default pasará a ser NULL en lugar del CURRENT_TIMESTAMP.
Timezones
Nomenclaturas
Signed offset: +/-hh:mm, por ejemplo, +01:00 para Madrid
Named timezone: por ejemplo, US/Western. Necesita las tablas de timezones en la BD mysql.
SYSTEM: tomar el huso horario del sistema operativo. Es el huso por defecto.
Variable time_zone (global/session).
Función CONVERT_TZ()
Atributos
Si se introduce un valor negativo en un campo UNSIGNED, se guardará 0.
Los campos ZEROFILL se hacen automáticamente UNSIGNED.
AUTO_INCREMENT solo se puede aplicar a enteros NOT NULL que sean PK o UNIQUE. Si se inserta un valor concreto en un campo AUTO_INCREMENT, el contador se situará en ese valor + 1
Si se inserta 0 en un campo AUTO_INCREMENT, se guardará el auto-incremental que corresponda, a no ser que el modo NO_AUTO_VALUE_ON_ZERO esté activado.
MyISAM permite una PK combinada con un campo AUTO_INCREMENT, en cuyo caso se crearán tantas secuencias como valores distintos haya del campo no-autoincremental.
CHARACTER SET = CHARSET
COLLATE (collation)
BINARY es un atributo que especifica collation binario.
DEFAULT no se puede aplicar a TEXT, BLOB ni campos AUTO_INCREMENT.
Si no se especifica en DEFAULT, el valor por defecto es 0 para números, '' para cadenas, el primer miembro para ENUMs y 0000-00-00 00:00:00 para fechas (excepto TIMESTAMP, solo si son DEFAULT 0).
PRIMARY KEY y UNIQUE crean sendas claves. Prohibido para cammpos TEXT y BLOB.
Valores inválidos y por defecto
En campos sin DEFAULT, si el strict mode no está activado, se aplicará el valor por defecto para el tipo de campo. Por ejemplo, 0 en INTs. Si el strict mode está activado, lanzará error. En tablas transaccionales se hará rollback, y en no transaccionales se insertarán los valores anteriores al causante del error.
En ENUM, si el valor no está definido, se insertará ''.
En SET, si un valor no está definido, pero otros sí, se descartará el no definido y se insertarán los válidos.
Al transformar un campo SET en ENUM, no se mantienen los miembros. Al transformar ENUM en SET, sí.
Al transformar un campo NULL en NOT NULL, los valores NULL se convertirán en el valor por defecto para el data type.
Al insertar NULL en campos NOT NULL, si la inserción es simple, da error. Si es múltiple, asignará el valor por defecto para el data type. Esto es así en cualquier circunstancia de valor inválido para evitar actualizaciones parciales en tablas no transaccionales, a no ser que se active el modo sql STRICT_ALL_TABLES, que lanzará error cuando haya un valor inválido siempre.
La conversión automática de cadena a fecha solo funcionará si se respeta el formato YYYY-MM-DD
Una fecha no válida, por ejemplo, 2009-02-31, se transforma en 0000-00-00 en modo no estricto, y lanza un error en modo estricto.
El modo sql NO_ZERO_DATE lanza error al recibir un valor temporal 0000-00-00
El modo sql NO_ZERO_IN_DATE lanza error al recibir un valor temporal con ceros en algún componente de la fecha. Con el modo sql ALLOW_INVALID_UPDATES se desactiva esta comprobación.
ERROR_FOR_DIVISION_BY_ZERO, NO_ZERO_DATE y NO_ZERO_IN_DATE solo funcionan en modo estricto.
TRADITIONAL es el modo sql más restrictivo, y es una combinación de NO_ZERO_DATE, NO_ZERO_IN_DATE y ERROR_FOR_DIVISION_BY_ZERO.
Con INSERT IGNORE y UPDATE IGNORE se eliminan silencian los errores de validación para una sola sentencia.
Respuestas del test:
DECIMAL ✓
VARCHAR(100) ½ in the special case where all the values are 100 chars long, CHAR will be more efficient
Using a case-sensitive collation, e.g. utf8_spanish_cs ✓
In a multi-byte character set, one character might allocate more than 1 byte. ½ binary strings have no charset nor collation.
MEDIUMINT UNSIGNED, whose maximum value is ~16M. It requires 3 bytes. ✓
VARCHAR(2000). It requires 302 bytes, because values longer than 256B take 2B for field length. ½ TEXT is valid as well
1001-01-01 ✗ 1000-01-01
10-02-2008, WARNING or ERROR if STRICT_MODE is applicable ✗ 2010-02-08, 2069-12-31, 1970-01-01
NULL, since it's not a valid date. ✗ ERROR in NO_ZERO_DATE mode, 2012-00-00 if NO_ZERO_DATE is not enabled because "12" is understood
a, b, d ✗ DOUBLE takes 8 bytes, whereas DECIMAL just 4
b, c ✓
10 bytes if a single-byte character set is chosen or the widest character of the charset if a multi-byte one in chosen. ✓
No, MySQL will allocate 3 bytes per char, allowing any utf8 value to be stored, and keeping the field fixed-length. ✓
No, it's not true. By default, charset and collations are taken from the table, but it can be declared for each field independently. ✓
No, it doesn't. ✓
No, it's not true, because binary strings store bytes, and non-binary strings store characters, which makes a difference on mb charsets. ✓
d ✓
a, b, c, d ✗ c is false. Timestamps are stored in UTC.
Yes, it has the default behavior, which is DEFAULT CURRENT_TIMESTAMP, ON UPDATE CURRENT_TIMESTAMP. To override it, declare the field with DEFAULT NULL or another DEFAULT value. ✗ Pregunta mal entendida: se trata de declarar ESE comportamiento explícitamente
It will store current timestamp in a) and c), and 1970-01-01 00:00:00 in b) ✗ b) and c) will throw error
12 ✓
2^8 = 255 if it's UNSIGNED. If not, 127 ✗ 127, because not UNSIGNED clause was specified
MEDIUMBLOB, VARCHAR(250) ✓
2000+2 ✓
SELECT @@global.time_zone, SELECT @@session.time_zone, SET time_zone='+01:00', SELECT @@session.time_zone ½ SET SESSION time_zone
c ✗ d) because changing the server's timezone doesn't affect the stored values, which are always stored in UTC.
SELECT LAST_INSERT_ID(), the same value because LAST_INSERT_ID() only affects to those rows entered by the current user. ✓
The second row will have the values (0, '') because they are the intrinsic default values for those data types. ✗ (0,0)
yes ✓
TIMESTAMP NULL DEFAULT NULL ½ TIMESTAMP NULL
When not specified, it stores the current time and date by default. ✓
When the row is updated and a value for the TIMESTAMP field is not specified, the current timestamp is stored. ✓
updated TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, created TIMESTAMP DEFAULT CURRENT_TIMESTAMP ✗ created TIMESTAMP DEFAULT 0, updated TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
SET time_zone='-05:00'; ✓
a ✓
STRICT_ALL_TABLES, non-transactional table. ½ STRICT_TRANS_TABLES. Si fuese ALL_TABLES no habría continuado tras el error
(1, 0001), (10000, 10000) ✓
(1, 22 as character, ?) ✗ (1, '22', 0000-00-00)
(255, 'yoodo', 1001-12-31) because 1000 is truncated to unsigned TINYINT max value, 'yoodoo' truncated to 5 chars and 999 to its closest valid value (1000) ✗ (255, 'yoodo', 0000-00-00)
(null, null, null) ✓
(0, the character #10, null) ✗ (0, '10', 0000-00-00)
(0, 0, '2000-02-29') ✗ (0, '-1', 0000-00-00)
False. It's the opposite: one collation belongs to exactly one charset. One charset can have many collations, e.g. utf -> utf8_spanish_ci, utf8_swedish_ci ✓
d ✓
With the function DATE_FORMAT() ½ ...and TIME_FORMAT()
ts1 TIMESTAMP DEFAULT NULL ✗ ts1 TIMESTAMP NULL
NULL, since the field is declared as NULL ✓
NULL, since it is the default value ✗ 0000-00-00 because 'string' is an invalid DATETIME value, so zero is inserted instead.
✗ 2020-02-02 08:21:39
✗ 2002-02-08 21:39:00
✗ 0000-00-00 00:00:00
2002-02-28 23:59:59 ✗ 0000-00-00 00:00:00
'Lennart', since NULL is treated as ''. ✗ NULL, because anything concatenated with NULL results in NULL
'1 plus 1 equals 2' ✓
2, since ' equals 2' is converted to 0 ✓
3.1, since '1.1 equals GUESS!' is converted to 1.1 ✓
1, since NULL is converted to 0 ✗ NULL, because any arithmetic operation with NULLL results in NULL
Africa, 0 ✗ 1
NULL, NULL ✗ '', 0
NULL, NULL ✗ '', 0 because it's not valid
Africa ✗ '', 0 because it's not valid
America ✗ 'Africa', 1 because Africa is the #1 member
NULL ✗ 'Africa', because MySQL converts '1' to 1, which corresponds to Africa
NULL ✓
col1=NULL, col2=0, col3=42 since they are their defaults ✓
col13=NULL, col15='' ✗ col15='doo' because it's the first member
col14=NULL, col16='' ✓
Since it's AUTO_INCREMENT, it can be executed until maximum TINYINT value (127) is reached. Then, an error occurs because of duplicated primary key (127) ✓
Unquoted: letras, números, _ y $ (NO digitos solamente, NO expresiones como 1e5 o 0x1)
Quoted: cualquier carácter, excepto ascii(0) y ascii(255). NO espacio solo. NO . \ y / en nombres de BBDD y tablas
Todos los identificadores son case-insensitive, excepto los de BBDD y tablas, que obedecen al SO, aunque LOWER_CASE_TABLE_NAMES hace que sean case-insensitive también.
Los campos se pueden identificar con qualified names completos: bd.tabla.campo. Los triggers y procedimientos almacenados también se pueden calificar.
Se entrecomilla con ` o ' y si ANSI_QUOTES está activado, con "
No se deben usar nombres de funciones porque algunos coinciden con palabras reservadas y porque si IGNORE_SPACE está activado, expresiones con paréntesis podrían ser ambiguas, e.g. INSERT INTO COUNT (id) ...
Las palabras reservadas y nombres de funciones son case-sensitive.
Respuestas del test:
a ✗ b
a) only with ansi_quotes, b) idem, c) yes, d) only with ansi_quotes ✗ a) fail b), c) and d) succeed
error. it must be quoted ✓
succeed ✓
succeed ✗ single quotes can be used for alias, but not table or DB names
succeed ✓
error ✓
error ✗ error if IGNORE_SPACE is enabled
succeed ✓
succeed ✓
succeed ✗ succeed only if the SO supports that characters
succeed ✓
succeed ✓
It seems like database was created in a Windows server and moved to a UNIX one later. To solve it, enable LOWER_CASE_TABLE_NAMES. To prevent it, use consistent identifiers. ✓
Every table has a tablename.frm format file. Data files depend on storage engine:
MyISAM: tablename.MYD for data and tablename.MYI for indexes
InnoDB: multiple tables share the same files (tablespaces)
MEMORY: data not stored in files, but in memory
SHOW ENGINES
Límites: los del sistema operativo. Para evitarlos, se pueden usar tablas MERGE para unir varias tablas MyISAM, así como cambiar de FS o SO.
CREATE TABLE [IF NOT EXISTS] [bd.]nombre (campos, indices) ENGINE = motor
ALTER TABLE t ENGINE = motor
La variable storage_engine especifica el motor por defecto
Si al crear una tabla se especifica un motor no válido (por ejemplo, uno obsoleto), se asigna el motor por defecto y se lanza warning
CREATE TABLE nombre SELECT ... crea una nueva tabla con los campos del SELECT, pero no copia índices, PK ni AUTO_INCREMENT
CREATE TABLE nombre LIKE origen es como CREATE TABLE SELECT pero sí copia índices, PK y AUTO_INCREMENT. Sin embargo, NO copia foreign keys
Tablas temporales
CREATE TEMPORARY TABLE (misma sintaxis)
Se crean para cada sesión, por lo que distintos clientes pueden crear tablas temporales con el mismo nombre
Se puede crear una tabla temporal con el mismo nombre que una no-temporal, en cuyo caso la no-temporal quedará invisible durante la sesión
No se puede usar RENAME TABLE con tablas temporales, sino solo ALTER TABLE
ALTER
ALTER TABLE tabla DROP campo
ALTER TABLE tabla ADD definición_de_nuevo_campo [AFTER|BEFORE] campo_existente
ALTER TABLE tabla MODIFY campo definición_de_campo
ALTER TABLE tabla CHANGE campo nuevo_nombre definición_de_campo
ALTER TABLE tabla RENAME TO nuevo_nombre = RENAME tabla TO nuevo_nombre
ALTER TABLE operacion1, operacion2, operacion3 ... donde operacion es una de las operaciones anteriores
Eliminación
DROP TABLE t1, t2, ...
DROP TABLE IF EXISTS t1 (si t1 no existe, lanza warning)
DELETE FROM tabla
TRUNCATE tabla
Índices
Tres tipos: PRIMARY, UNIQUE, INDEX. Otros dos tipos adicionales, FULLTEXT y SPATIAL, no entran en el examen
CREATE TABLE nombre ( definición_de_campo1, PRIMARY KEY|UNIQUE|INDEX [nombre] (campo1) )
El campo con PRIMARY KEY debe ser NOT NULL
Campos UNIQUE pueden ser NULL, y contener varias filas con el valor NULL para el campo UNIQUE
También se puede especificar en le definición del campo: CREATE TABLE tabla (campo INT NOT NULL [PRIMARY KEY|UNIQUE])
Las PRIMARY KEY no tienen nombre nunca.
ALTER TABLE tabla ADD PRIMARY KEY|UNIQUE|INDEX [nombre] (campo)
CREATE [UNIQUE] INDEX [USING HASH|BTREE] nombre ON tabla (campo) (es obligatorio el nombre)
INDEX USING [HASH|BTREE] (campo) algoritmos: HASH (por defecto, mejor con valores únicos) o BTREE (mejor con valores repetidos)
Los algoritmos de indexación solo están disponibles en tablas MEMORY
DROP INEX indice ON tabla = ALTER TABLE tabla DROP INDEX indice, donde indice puede ser PRIMARY para PK.
Ver metadatos de las tablas
SHOW TABLES [FROM database] [LIKE 'patron']
SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES
SHOW CREATE TABLE tabla
DESCRIBE tabla = SHOW FIELDS FROM tabla = SHOW COLUMNS FROM tabla
SHOW INDEX FROM tabla
Respuestas del test:
false, there's a limit of 2,000,000,000 tables in the same tablespace ✓
true ✓
ALTER TABLE DROP PRIMARY KEY; DROP INDEX PRIMARY; ✗ DROP INDEX PRIMARY ON table;
PRIMARY, UNIQUE, INDEX ✗ faltan FULLTEXT y SPATIAL
The field must be NOT NULL, because UNIQUE indexes can contain multiple NULL values ✓
DROP TABLE IF EXISTS table; it will raise a warning ✓
true ✓
false; they are empty by default ✓
false; you can specify the database in the name of the new table: CREATE TABLE database.table ✓
CREATE TABLE IF NOT EXISTS table ...
It has no comma between PRIMARY KEY and name CHAR(10) ✓
CREATE TABLE test.City SELECT * FROM World.City; CREATE TABLE test.City LIKE SELECT * FROM World.City; ✗ CREATE TABLE test.City LIKE world.City; INSERT INTO test.City SELECT * FROM world.City;
yes, because the key can be unique if the other field is NOT NULL ✗ all PK fields must be NOT NUll
ALTER TABLE mytable ADD col0 INT before col1, ADD col2 INT after col1, ADD col4 INT AFTER col3 ✓ "AFTER col3" sobra, y "before col1" puede ser FIRST
SHOW INDEXES FROM table; SHOW CREATE TABLE table; ✗ SHOW INDEX FROM tbl, no "indexes"
CREATE TABLE tbl (col1 INT NOT NULL, col2 INT NOT NULL, PRIMARY KEY(col1, col2)); ✓
TRUNCATE TABLE tablename; ✓
SHOW TABLES FROM test LIKE '%test%'; SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME LIKE '%test%'; ✗ AND TABLE_SCHEMA = 'test'
SHOW COLUMNS FROM test.mytest LIKE 'id%'; SHOW FIELDS FROM test.mytest LIKE 'id%'; ✓
SHOW CREATE TABLE test.mytest; ✓
The default engine has been changed in the storage_engine variable. You can append ENGINE=MyISAM at the end of the CREATE TABLE statement to make sure that MyISAM is used for the table. ✓
SET GLOBAL storage_engine = InnoDB; ✓
Using a MERGE table with MyISAM tables; upgrading the file system; upgrading the operating system ✗ falta pasar de MyISAM a InnoDB
ALTER TABLE tbl DROP INDEX idx_id; ALTER TABLE tbl ADD INDEX idx_id (id); ✓
UNIQUE admits NULL values, even in more than 1 row; UNIQUE cannot be used with AUTO_INCREMENT; there can't be more than one AUTO_INCREMENT index on a table ✓
PRIMARY KEY ✓
You cannot create a table with no engine. If you don't specify it, it will be created with the default engine. If you want to change it later, you can do it with ALTER TABLE table ENGINE = engine_name; ✓ habla de bases de datos, no de motores!!!
CREATE TABLE mytbl (col1 INT(10) UNSIGNED NOT NULL DEFAULT 0 PRIMARY KEY, col2 CHAR(50) NOT NULL UNIQUE, col3 CHAR(50) NOT NULL INDEX); ✓
true ✓
true ✓
ALTER TABLE table ADD COL [type]; ✗ column names must be unique regardless of lettercase
no, a UNIQUE index admits several NULL values ✓
ALTER TABLE mytable ADD PRIMARY KEY (col1, col2); ✓
An auto-generated INDEX name is assigned ✓ you have to specify a name if you use CREATE INDE
no ✓
✗ RENAME TABLE t_archive TO t_archive_lastyear, t_active TO t_archive, t_template TO t_active;
You can't rename temporary tables ✓
SHOW TABLES FROM test; ✓
SHOW COLUMNS FROM test.mytest; ✓
The MySQL server was compiled without InnoDB, but since it is a valid engine name, it doesn't cause an error. ✗ ...or it was disabled at startup
Changing the storage_engine option when launching the server or in my.cnf ✗ only in startup (although startup command can be stored in a file)
Los alias pueden llevar comillas sencillas, dobles o tildes.
Los alias no se pueden usar en los WHERE
SELECT DISTINCT distingue los duplicados de cadenas aplicando el collation que toque.
COUNT(DISTINCT campo)
WITH ROLLUP aplica la función de agregación (COUNT, MAX, MIN, SUM) a todos los elementos
UNION puede unir tablas heterogéneas, siempre y cuando los SELECT tengan el mismo número de columnas. El tipo de las columnas finales será el menos restrictivo.
Con UNION, se puede usar ORDER BY en el resultset total si se pone también LIMIT
Respuestas del test:
SELECT d FROM t ORDER BY d ASC; SELECT d FROM t ORDER BY d DESC; ✗ SELECT MIN(d) FROM t; SELECT MAX(d) FROM t;
SELECT * FROM t ORDER BY d ASC; SELECT * FROM t ORDER BY d DESC; ✗ ...LIMIT 1
SELECT Name FROM Country WHERE IndepYear IS NOT NULL ORDER BY IndepYear DESC; SELECT Name FROM Country WHERE IndepYear IS NOT NULL ORDER BY IndepYear ASC; ✗ ...LIMIT 1, ...LIMIT 1
FROM, WHERE, GROUP BY, HAVING, ORDER BY, LIMIT ✓
All except FROM ✓
SELECT fields FROM world.City ✓
SELECT * FROM City WHERE substr(Name, 0, 1) BETWEEN 'B' AND 'F' AND substr(Name, 0, 1) BETWEEN 'K' AND 'M' AND Population > 1000000 ORDER BY Name ASC; ✗ SELECT Name, Population FROM City WHERE ( (Name >= 'B' AND Name < 'G') OR (Name >= 'K' AND Name < 'N') ) AND Population > 1000000 ORDER BY Name ASC;
SELECT name as Pet, MONTH(birth) as Month, YEAR(birth) as Year FROM petbirth ORDER BY birth DESC; ✓
Unpredictable results (you don't really know which are the fields), performance issues (more information than needed). ½ If you want to retrieve the table columns in a particular order, you cannot use *.
SELECT c FROM t ORDER BY c COLLATE latin1_general_ci, 2) SELECT c FROM t ORDER BY c COLLATE latin1_general_cs, 3) SELECT c FROM t ORDER BY c COLLATE latin1_bin ✓
SELECT CountryCode FROM CountryLanguage GROUP BY CountryCode; ✓
SELECT name, birth FROM petbirth ORDER BY birth ASC LIMIT 1; ✓
a) SELECT gender, COUNT() FROM pet WHERE gender GROUP IS NOT NULL; ✗
b) SELECT species, COUNT() individuals FROM pet GROUP BY species ORDER BY individuals DESC; ½ faltan alias
c) SELECT species, COUNT() individuals FROM pet WHERE species IN ('dog', 'cat') GROUP BY species ORDER BY individuals DESC; ✓
c) SELECT species, COUNT() individuals FROM pet GROUP BY species HAVING species IN ('dog', 'cat') ORDER BY individuals DESC; ✓
a) SELECT unit Unit, COUNT(pid) AS Employees, SUM(salary) AS Total, AVG(salary) Average FROM personnel GROUP BY unit ORDER BY Total DESC; ✓
b) SELECT unit Unit, MAX(salary) AS High, MIN(salary) as Low FROM personnel GROUP BY unit; ✓
SELECT GROUP_CONCAT(Name) FROM Country WHERE Population > 100000000 GROUP BY Continent; ½ falta campo en FROM
SELECT GROUP_CONCAT(District) AS Dutch Districts FROM City WHERE CountryCode = 'NLD'; ✗ GROUP_CONCAT(District ORDER BY District SEPARATOR " - ")
a) 9, b) 8, c) 2, d) 5 ✓
SELECT species as Species, gender as Gender, COUNT(species, gender) Total FROM pet GROUP BY species, gender ORDER BY species; ✓
SELECT Continent, COUNT(*) FROM Country GROUP BY Continent WITH ROLLUP; ✓
a) SELECT name TeamMember, job TeamTask FROM project1.user UNION (SELECT nick, task FROM project2.users) UNION (SELECT member, job FROM project3.members) ✗ UNION ALL
b) SELECT name TeamMember, job TeamTask FROM project1.user UNION SELECT nick, task FROM project2.users UNION SELECT member, job FROM project3.members
estoy preparando el examen "MySQL Developer", te agradezco este material isra00. ¿Podrias explicarme k es cada seccion ?
¿A que te refieres con "Respuestas del test:"?¿donde esta ese test?
Te parecio muy dificil o con revisar el PDF es suficiente?¿Lo ves util para ofertas de trabajo(de certificaciones de DB solo se requieren SQLserver/ORACLE)? ¿Me puedes enviar(por privado mejor) mas recursos que tengas(VCEs, examenes on-line,Q&A))?
estoy preparando el examen "MySQL Developer", te agradezco este material isra00. ¿Podrias explicarme k es cada seccion ?
¿A que te refieres con "Respuestas del test:"?¿donde esta ese test?
Te parecio muy dificil o con revisar el PDF es suficiente?¿Lo ves util para ofertas de trabajo(de certificaciones de DB solo se requieren SQLserver/ORACLE)? ¿Me puedes enviar(por privado mejor) mas recursos que tengas(VCEs, examenes on-line,Q&A))?
Gracias isra00, saludos:D