1.7. Cumplimiento de los estándares por parte de MySQL

MySQL 5.0

1.7. Cumplimiento de los estándares por parte de MySQL

Esta sección describe cómo MySQL se relaciona con el estándard ANSI/ISO SQL. MySQL Server tiene varias extensiones del estándard SQL, y aquí puede encontrar cuáles son y cómo usarlas. También puede encontrar información sobre lagunas de funcionalidades en MySQL Server, y cómo tratar algunas diferencias.

El estándard SQL ha ido evolucionando desde 1986 y existen varias versiones. En este manual, "SQL-92" se refiere al estándard publicado en 1992, "SQL:1999" se refiere al estándard publicado en 1999, y "SQL:2003" se refiere a la versión actual del estándard. Usamos la frase "el estándard SQL" para referirnos a la versión actual del estándard SQL en cualquier momento.

Nuestro objetivo es no restringir la usabilidad de MySQL ningún uso sin una muy buena razón para ello. Incluso si no tenemos los recursos para hacer un desarrollo para cada uso posible, estamos siempre deseando ayudar y ofrecer sugerencias a gente que intenta usar MySQL en nuevos campos.

Uno de nuestros fines principales con el producto es continuar el trabajo hacia el cumplimiento del estándard SQL, pero sin sacrificar velocidad o fiabilidad. No tememos añadir extensiones a SQL o soporte para funcionalidades no SQL si esto aumenta la usabilidad de MySQL Server para un gran segmento de nuestra base de usuarios. La interfaz en MySQL Server 4.0 es un ejemplo de esta estrategia. Consulte Sección 13.2.3, “Sintaxis de .

Continuamos soportando bases de datos transaccionales y no transaccionales para satisfacer uso crítico 24/7 y uso pesado en entornos Web o log.

MySQL Server fue diseñado originalmente para trabajar con bases de datos de tamaño medio (de 10 a 100 millones de regitros, o unas 100MB por tabla) en máquinas pequeñas. Hoy MySQL Server soporta bases de datos de tamaño de terabytes, pero el código todavía puede compilarse en una versión reducida adecuada para dispositivos hand-held o incrustados. El diseño compacto de MySQL Server hace el desarrollo en ambas direcciones posible sin ningún conflicto en el árbol fuente.

Actualmente, no tratamos soporte en tiempo real, aunque la capacidad de replicación en MySQL ofrece funcionalidades significativas.

Existe soporte para clusters de bases de datos a través de soluciones de terceras partes, así como la integración de tecnología NDB Cluster, disponible desde la versión 4.1.2. Consulte Capítulo 16, MySQL Cluster.

También estamos mirando de proveer de soporte XML en el servidor de base de datos.

1.7.1. Estándares utilizados por MySQL

Estamos intentando soportar en estándard ANSI/ISO completamente, pero sin hacer concesiones a la velocidad y calidad del código.

Niveles ODBC 0-3.51.

1.7.2. Selección de modos SQL

MySQL Server puede operar en distintos modos SQL y puede aplicar dichos modos de forma diferente para distintos clientes. Esto permite a una aplicación adaptar el funcionamiento del servidor a sus propios requerimientos.

Los modos definen la sintaxis que MySQL debe soportar y qué clase de validaciones debe efectuar a los datos. Esto hace más fácil usar MySQL en un conjunto de entornos diferentes y usar MySQL junto con otros servidores de bases de datos.

Puede inicializar el modo SQL por defecto inicializando mysqld con la opición . Empezando en MySQL 4.1., se puede cambiar el modo tras inicializar mediante la variable con un comando .

Para más información acerca de especificar el modo del servidor, consulte Sección 5.3.2, “El modo SQL del servidor”.

1.7.3. Ejecutar MySQL en modo ANSI

Puede decirle a mysqld que use el modo ANSI con la opción al arrancar. Consulte Sección 5.3.1, “Opciones del comando mysqld.

Ejecutar el servidor en modo ANSI es lo mismo que inicializarlo con las siguientes opciones (especifique el valor de en una única línea):

--transaction-isolation=SERIALIZABLE
--sql-mode=REAL_AS_FLOAT,PIPES_AS_CONCAT,ANSI_QUOTES,
IGNORE_SPACE

En MySQL 4.1, puede conseguir el mismo efecto con los siguientes 2 comandos (especifique el valor de en una única línea):

SET GLOBAL TRANSACTION ISOLATION LEVEL SERIALIZABLE;
SET GLOBAL sql_mode = 'REAL_AS_FLOAT,PIPES_AS_CONCAT,ANSI_QUOTES,
IGNORE_SPACE';

Consulte Sección 1.7.2, “Selección de modos SQL”.

En MySQL 4.1.1, la opción puede inicializarse con el siguiente comando:

SET GLOBAL sql_mode='ansi';

En ese caso, el valor de la variable se especifica para todas las opciones que son relevantes en el modo ANSI. Puede comprobar el resultado de la siguiente manera:

mysql> SET GLOBAL sql_mode='ansi';
mysql> SELECT @@global.sql_mode;
        -> 'REAL_AS_FLOAT,PIPES_AS_CONCAT,ANSI_QUOTES,
            IGNORE_SPACE,ANSI';

1.7.4. Extensiones MySQL al estándar SQL

MySQL Server incluye algunas extensiones que probablemente no encontrará en otras bases de datos SQL. Tenga en cuenta que si lo usa, su código no será portable a otros servidores SQL. En algunos casos, puede escribir código que incluya extensiones MySQL, pero siendo portable, mediante comentarios de la forma . En ese caso, MySQL parsea y ejecuta el código dentro de los comentarios como si fuera cualquier otro comando de MySQL, pero otros servidores SQL ignorarán la extensión. Por ejemplo:

SELECT /*! STRAIGHT_JOIN */ col_name FROM table1,table2 WHERE ...

Si añade un número de versión tras el carácter '', la sintaxis dentro del comentario se ejecuta sólo si el número de versión de MySQL es igual o mayor que el especificado:

CREATE /*!32302 TEMPORARY */ TABLE t (a INT);

Eso significa que si tiene la Versión 3.23.02 o posterior, MySQL Server usa la palabra clave .

La siguiente lista describe las extensiones MySQL, organizadas por categorías.

  • Organización de los datos en disco

    MySQL Server mapea cada base de datos a un directorio bajo el directorio de datos de MySQL, y las tablas dentro de cada directorio como ficheros. Esto tiene algunas implicaciones:

    • Nombres de bases de datos y nombres de tablas son case sensitive en MySQL Server en sistemas operativos que tienen nombres de ficheros case-sensitive (como la mayoría de sistemas Unix). Consulte Sección 9.2.2, “Sensibilidad a mayúsuclas y minúsculas de identificadores”.

    • Puede usar comandos de sistema estándard para hacer copia de seguridad, renombrar, mover, borrar y copiar tablas de tipo o . Por ejemplo, para renombrar el nombre de una tabla renombre los archivos , , y que correspondan a la tabla.

    Nombres de bases de datos, tablas, índices, columnas o alias pueden empezar con un dígito (pero no pueden consistir únicamente de dígitos).

  • Sintaxis general del lenguaje

    • Cadenas de carácteres deben limitarse por '' o '', no sólo por ''.

    • Use '' como un carácter de escape en cadenas de carácteres.

    • En comandos SQL, puede acceder a tablas de distintas bases de datos con la sintaxis . Algunos servidores SQL proporcionan la misma fucnionalidad, pero lo llaman . MySQL Server no soporta espacios de tablas como los usados en comandos como: .

  • Sintaxis de comandos SQL

  • Tipos de columnas

    • Los tipos de columnas , , , y los distintos tipos y .

    • Los atributos de columnas , , , , y .

  • Funciones y operadores

    • Para facilitar a los usuarios que vienen de otros entornos SQL, MySQL Server soporta alias para varias funciones. Por ejemplo, todas las funciones de cadenas de carácteres soportan sintaxis estándard SQL y ODBC.

    • MySQL Server entiende los operadores y para OR lógica y AND, como en el lenguaje de programación C. En MySQL Server, y son sinónimos, como lo son y . Debido a esta sintaxis, MySQL Server no soporta el operador estándard SQL para concatenar cadenas de carácteres; use en su lugar . Como toma cualquier número de argumentos, es fácil adaptarse al uso del operador a MySQL Server.

    • Uso de donde tiene más de un elemento.

    • Todas las comparaciones de cadenas de carácteres son case-insensitive por defecto, con la ordenación determinada por el conjunto de carácteres actual (ISO-8859-1 Latin1 por defecto). Si no quiere que sea así, puede declarar las columnas con el atributo o usar la conversión , que hace que las comparaciones se hagan usando el código de carácteres subyacente en lugar del orden léxico.

    • El operador es sinónimo de . Esto es que es equivalente a . se soporta para programadores C y por compatibilidad con PostgreSQL.

    • Los operadores , , ,, ,, , , , , , o se pueden usar en comparaciones de columnas a la izquierda del en comandos . Por ejemplo:

      mysql> SELECT col1=1 AND col2=2 FROM ;
      
    • La función retorna el valor más reciente. Consulte Sección 12.9.3, “Funciones de información”.

    • se permite en columnas numéricas.

    • Los operadores de expresiones regulares extendidos y .

    • o con un argumento o más de dos argumentos. (En MySQL Server, estas funciones pueden tomar cualquier número de argumentos.)

    • Las funciones , , , , , , , , , , , , , , y .

    • Uso de para eliminar espacios en substrings. Funciones estándard sólo SQL soportan eliminar carácteres simples.

    • Las funciones , , , , y . Consulte Sección 12.10, “Funciones y modificadores para cláusulas .

1.7.5. Diferencias en MySQL del estándar SQL

Intentamos que MySQL Server siga los estándares ANSI SQL y el estándard ODBC SQL, pero MySQL Server ejecuta operaciones de forma distinta en algunos casos:

1.7.5.1. Subconsultas

MySQL 4.1 soporta sub-consultas y tablas derivadas. Una "sub-consulta" es un comando anidado en otro comando. Una tabla "derivada" (una vista sin nombre) es una subconsulta en la cláusula de otra consulta. Consulte Sección 13.2.8, “Sintaxis de subconsultas”.

Para versiones MySQL anteriores a la 4.1, la mayoría de subconsultas pueden reescribirse usando joins u otros métodos. Consulte Sección 13.2.8.11, “Re-escribir subconsultas como joins en versiones de MySQL anteriores” para ejemplos que muestren cómo hacerlo.

1.7.5.2.

MySQL Server no soporta la sintaxis de extensiones Sybase SQL: . En su lugar, MySQL Server soporta la sintaxis estándard SQL , que básicamente es lo mismo. Consulte Sección 13.2.4.1, “Sintaxis de .

INSERT INTO tbl_temp2 (fld_id)
    SELECT tbl_temp1.fld_order_id
    FROM tbl_temp1 WHERE tbl_temp1.fld_order_id > 100;

Alternativamente, puede usar o .

Para al versión 5.0, MySQL soporta con variables de usuario. La misma sintaxis puede usarse dentro de procedimientos almacenados usando cursores y variables locales. Consulte Sección 19.2.9.3, “La sentencia .

1.7.5.3. Transacciones y operaciones atómicas

MySQL Server (versiones 3.23-max y todas las versiones 4.0 y posteriores) soportan transacciones con los motores trasaccionales y . proporciona completa compatibilidad . Consulte Capítulo 14, Motores de almacenamiento de MySQL y tipos de tablas.

Los otros motores no transaccionales en MySQL Server (como ) siguen un paradigma diferente para integridad de datos llamado "operaciones atómicas". En términos transaccionales, tablas operan en modo . Operaciones atómicas a menudo ofrecen integridad comparable con mejor rendimiento.

MySQL Server soporta ambos paradigmas, puede decidir si su aplicación necesita la velocidad de operaciones atómicas o el uso de características transaccionales. Esta elección puede hacerse para cada tabla.

Como se ha dicho, el compromiso entre tipos de tablas transaccionales y no transaccionales reside principalmente en el rendimiento. Tablas transaccionales tienen requerimientos significativamente mayores para memoria y espacio de disco, y mayor carga de CPU. Por otra parte, tipos de tablas transaccionales como también ofrece muchas características significativas. El diseño modular de MySQL Server permite el uso concurrente de distintos motores de almacenamiento para cumplir distintos requerimientos y mostrarse óptimo en todas las situaciones.

Pero, ¿cómo usar las características de MySQL Server para mantener integridad de forma rigurosa incluso en tablas no transaccionales como , y cómo se comparan estas características con los tipos de tablas transaccionales?

  1. Si su aplicación está escrita de forma que dependa en que pueda llamar a en lugar de en situaciones críticas, es preferible usar transacciones. Transacciones aseguran que actualizaciones no acabadas o actividades corruptas no se ejectuen en la base de datos; el sevidor tiene la oportunidad de hacer un rollback automático para mantener la base de datos a salvo.

    Si usa tablas no transaccionales, MySQL Server le permite solucionar problemas potenciales en prácticamente todos los casos simplemente incluyendo chequeos antes de las actualizaciones y ejecutando scripts sencillos que comprueban que la consistencia de la base de datos, dando una advertencia o reparando automáticamente cualquier incosistencia. Simplemente usando el log de MySQL o añadiendo un log extra, normalmente puede arreglar tablas sin pérdida de integridad en los datos.

  2. Normalmente, las actualizaciones transaccionales críticas pueden reescribirse como atómicas.Generalmente hablando, todos los problemas de integridad que resuelven las transacciones pueden resolverse con o actualizaciones atómicas, asegurando que no se aborten automáticamente desde el servidor, el cuál es un problema habitual en sistemas de bases de datos transaccionales.

  3. Para tener un entorno fiable de MySQL, usando tablas transaccionales o no, sólo necesita tener copias de seguridad y el log binario activado. Con ello, puede recuperarse de cualquier situación de la que pueda hacerlo con cualquier otro sistema transaccional. Siempre es bueno tener copias de seguridad, independientemente del sistema de bases de datos usado.

El paradigma transaccional tiene sus ventajas y desventajas. Muchos usuarios y desarrolladores de aplicaciones dependen en la facilidad con la que pueden solucionar problemas donde un aborto parece ser o es necesario. Sin embargo, incluso si el paradigma de operaciones atómicas le es desconocido o está más familiarizado con las transacciones, considere el beneficio de la velocidad que pueden ofrecer las tablas no transaccionales, que puede ser de tres a cinco veces más rápido que las más optimizadas tablas transaccionales.

En las situaciones en las que la integridad es de máxima importancia, MySQL Server ofrece integridad a nivel de transacción incluso para tablas no transaccionales. Si bloquea tablas con , todas las actualizaciones se bloquean hasta que se hacen las comprobaciones necesarias. Si obtiene un bloqueo (el contrario a un bloqueo de escritura) para una tabla que permita inserciones concurrentes al final de la tabla, las lecturas están permitidas, así como las inserciones de otros clientes. Los registros insertados no puede verlos el cliente que tenga el bloqueo hasta que lo libere. Con , puede encolar inserciones en una cola local, hasta que los bloqueos se liberan, sin tener que esperar el cliente a que acabe la inserción. Consulte Sección 13.2.4.2, “Sintaxis de .

"Atómico", en el sentido en que nos referimos, no es nada mágico. Se trata que puede asegurar que mientras cada actualización específica está ejecutándose, ningún otro usuario puede interferir con ellas, y que nunca puede haber un rollback automático (lo que puede ocurrir con tablas transaccionales si no se es muy cuidadoso). MySQL Server garantiza que no hay dirty reads (lecturas sucias).

A continación se presentan algunas técnicas para trabajar con tablas no transaccionales:

  • Los bucles que necesiten transacciones normalmente pueden codificarse con la ayuda de , y no necesita cursores para actualizar registros en tiempo real.

  • Para evitar usar , puede usar la siguiente estrategia:

    1. Use para bloquear todas las tablas a las que quiere acceder.

    2. Compruebe las condiciones que deben darse antes de ejecutar la actualización.

    3. Actualice si todo es correcto.

    4. Use para liberar los bloqueos.

    Este es un método mucho más rápido que usar transacciones con posibles rollbacks, aunque no siempre. La única situación en que esta situación no funciona es cuando alguien mata el thread durante una actualización. En ese caso, todos los bloqueos se liberan pero algunas actualizaciones pueden no ejecutarse.

  • Puede usar funciones para actualizar registros en una única operación. Puede obtener una aplicación muy eficiente usando las siguientes técnicas:

    • Modifique columnas con su valor actual.

    • Actualice sólo aquéllas que hayan cambiado.

    Por ejemplo, cuando estamos actualizando la información de un cliente, sólo actualizamos los datos del cliente que han cambiado y comprobamos que los datos cambiados o datos que dependen de los datos cambiados, han cambiado respecto a los datos originales. El test para datos cambiados se hace con la cláusula en el comando . Si el registro no se ha actualizado, mostramos un mensaje al cliente: "Algunos de los datos actualizados han sido cambiados por otro usuario". A continuación mostramos los registros viejos junto a los nuevos en una ventana para que el usuario pueda decidir qué versión del registro de usuario usar.

    Esto nos da algo que es similar a bloqueo de columnas pero es incluso mejor ya que sólo actualizamos algunas de las columnas, usando valores que son relativos a sus valores actuales. Eso significa que el típico comando será algo así:

    UPDATE tablename SET pay_back=pay_back+125;
    
    UPDATE customer
      SET
        customer_date='current_date',
        address='new address',
        phone='new phone',
        money_owed_to_us=money_owed_to_us-125
      WHERE
        customer_id=id AND address='old address' AND phone='old phone';
    

    Esto es muy eficiente y funciona incluso si otro cliente ha cambiado los valores en las columnas o .

  • En muchos casos, los usuarios han querido usar y/o con la intención de administrar identificadores únicos. Se puede tratar de forma mucho más eficiente sin bloquear o rolling back usando columnas y la función SQL o la función de la API C . Consulte Sección 12.9.3, “Funciones de información”. Consulte Sección 24.3.3.34, “.

    Normalmente puede codificar la necesidad de bloqueo a nivel de registro. Algunas situaciones realmente lo necesitan, y las tablas lo soportan. Con tablas , puede usar una columna flag en la tabla y hacer algo como lo siguiente:

    UPDATE  SET row_flag=1 WHERE id=ID;
    

    MySQL retorna para el número de registros afectados si la fila ha sido encontrada y no era en el registro original.

    Puede imaginarlo como si MySQL Server cambiase la consulta anterior a:

    UPDATE  SET row_flag=1 WHERE id=ID AND row_flag <> 1;
    

1.7.5.4. Procedimientos almacenados (stored procedures) y disparadores (triggers)

Los procedimientos almacenados se implementan desde la versión 5.0. Consulte Capítulo 19, Procedimientos almacenados y funciones.

Funcionalidad básica para disparadores se implementa en MySQL desde la versión 5.0.2, con desarrollo adicional planeado para MySQL 5.1. Consulte Capítulo 20, Disparadores (triggers).

1.7.5.5. Claves foráneas (foreign keys)

En MySQL Server 3.23.44 y posteriores, el motor soporta chequeo para restricciones de claves foráneas, incluyendo , , y . Consulte Sección 15.6.4, “Restricciones (constraints) .

Para otros motores diferentes a , MySQL Server parsea la sintaxis de en comandos , pero no lo usa ni almacena. En el futuro, la implemantación se extenderá para almacenar esta información en el fichero de especificaciones de las tablas de forma que puedan obtenerla mysqldump y ODBC. En una etapa posterior, restricciones de claves foráneas se implementarán para tablas .

Restricciones de claves foráneas ofrecen distintos beneficios a los diseñadores de bases de datos:

  • Suponiendo un diseño adecuado de las relaciones, las restricciones de claves foráneas hacen más difícil que un programador introduzca inconsistencias en la base de datos.

  • Chequeo centralizado de restricciones por el servidor de base de datos hace que sea innecesario realizar esos chequeos en la parte de la aplicación, eliminando la posibilidad que distintas aplicaciones puedan no chequear todas las restricciones de la misma forma.

  • Usando actualizaciones y borrados en cascada puede simplificarse el código de aplicación.

  • Reglas diseñadas correctamente para claves foráneas pueden ayudar a documentar las relaciones entre tablas.

Tenga en cuenta que estos beneficios tienen el coste de un trabajo adicional para el servidor de base de datos para poder realizar todas las comprobaciones necesarias. Chequeos adicionales por parte del servidor afectan al rendimiento, lo que puede ser lo suficientemente malo para algunas aplicaciones como para evitarlo todo lo posible. (Algunas grandes aplicaciones comerciales han codificado la lógica de claves foráneas en el nivel de aplicación por esta razón.)

MySQL proporciona a diseñadores de bases de datos la posibilidad de elegir qué paradigma elegir. Si no necesita claves foráneas y quiere evitar la sobrecarga asociada con la integridad referencial, puede usar otro tipo de tabla como . (Por ejemplo, el motor ofrece muy buen rendimiento para aplicaciones que sólo realizan operaciones y , ya que las inserciones de pueden utilizar de forma concurrente con consultas. Consulte Sección 7.3.2, “Cuestiones relacionadas con el bloqueo (locking) de tablas”.)

Si elige no utilizar integridad referencial, tenga en cuenta las siguientes consideraciones:

  • Sin un chequeo por parte del servidor de integridad referencial, la aplicación debe realizar este trabajo. Por ejemplo, debe tener cuidado de insertar registros en tablas en el orden apropiado, y evitar crear registros con hijos huérfanos. También debe ser capaz de recuperarse de errores que ocurran durante inserciones múltiples.

  • Si es la única integridad referencial que necesita la aplicación, desde la versión 4.0 de MySQL Server puede usar comandos para borrar registros de distintas tablas con un único comando. Consulte Sección 13.2.1, “Sintaxis de .

  • Una forma de suplir la falta de es añadir el comando apropiado a su aplicación cuando borre registros de una tabla que no tenga clave foránea. En la práctica, esto es tan rápido como usar una clave foránea, y más portable.

Tenga en cuenta que el uso de claves foráneas puede provocar algunos problemas:

  • El soporte de claves foráneas arregla muchas cuestiones relacionadas con la integridad, pero todavía es necesario diseñar las claves cuidadosamente para evitar reglas circulares o combinaciones incorrectas de borrados en cascada.

  • Es posible crear una topología de relaciones que haga difícil restaurar tablas individuales de una copia de seguridad. (MySQL alivia esta dificultad permitiendo desactivar claves foráneas temporalmente al recargar una tabla que dependa de otras. Consulte Sección 15.6.4, “Restricciones (constraints) . Desde MySQL 4.1.1, mysqldump genera ficheros que utilizan esta características automáticamente al recargarse.)

Tenga en cuenta que las claves foráneas en SQL se usan para chequear y forzar integridad referencial, no para unir tablas. Si quiere obtener resultados de múltiples tablas a partir de un comando , debe usar un join entre ellas:

SELECT * FROM t1, t2 WHERE t1.id = t2.id;

Consulte Sección 13.2.7.1, “Sintaxis de . Consulte Sección 3.6.6, “Usar claves foráneas (foreign keys)”.

La sintaxis de sin se usa a menudo por aplicaciones ODBC para producir cláusulas automáticamente.

1.7.5.6. Vistas

Vistas (incluyendo vistas actualizables) se implementan en la versión 5.0 de MySQL Server. Las vistas están disponibles en las versiones binarias a partir de la 5.0.1. Consulte Capítulo 21, Vistas (Views).

Las vistas son útiles para permitir acceder a los usuarios a un conjunto de relaciones (tablas) como si fueran una sola, y limitar su acceso a las mismas. También se pueden usar las vistas para restringir el acceso a registros (un subconjunto de una tabla particular). Para control de acceso a columnas, puede usar el sofisticado sistema de privilegios de MySQL Server. Consulte Sección 5.6, “El sistema de privilegios de acceso de MySQL”.

Al diseñar la implementación de las vistas, nuestro ambicioso objetivo, dentro de los límites de SQL, ha sido la plena compatibilidad con la regla 6 de Codd para sistemas relacionales de bases de datos: "Todas las vistas que son actualizables en teoría, deben serlo en la práctica".

1.7.5.7. Empezar un comentario con ''

Algunas otras bases de datos SQL utilizan '' para comenzar comentarios. MySQL Server utiliza '' como carácter para comenzar comentarios. Puede utilizar comentarios estilo C con MySQL Server. Consulte Sección 9.5, “Sintaxis de comentarios”.

MySQL Server 3.23.3 y posteriores permiten comentarios del estilo '', mientras el comentario esté seguido de un carácter (o por un carácter de controlo como una nueva línea). Se necesita dicho espacio para evitar problemas con consultas SQL generadas automáticamente que usen algo parecido al código a continuación, donde se inserta automáticamente el valor de pago para :

UPDATE account SET credit=credit-!payment!

Piense acerca de lo que ocurre si el valor de es un valor negativo como :

UPDATE account SET credit=credit--1

es una expresión legal en SQL, pero si se interpreta como parte de un comentario, una parte de la expresión se descarta. El resultado es un comando que tiene un significado completamente distinto al deseado:

UPDATE account SET credit=credit

Este comando no produce ningún cambio en absoluto! Lo cual ilustra que permitir comentaros que empiecen con '' puede tener serias consecuencias.

Usando la implementación de este método de comentarios en MySQL Server desde 3.23.3, es seguro.

Otra medida de seguridad es que el cliente de líneas de comando mysql elimina todas las líneas que empiecen con ''.

La siguiente información sólo es relevante si utiliza versiones anteriores a la 3.23.3:

Si tiene un programa SQL en un fichero de texto que contenga comentarios del estilo '', debería utilizar la utilidad replace para convertir los comentarios antiguos en carácteres '' de la siguiente forma:

shell> replace " --" " #" < text-file-with-funny-comments.sql \
         | mysql 

en lugar del usual:

shell> mysql  < text-file-with-funny-comments.sql

También puede editar el fichero "a mano" para cambiar los comentarios '' a '':

shell> replace " --" " #" -- text-file-with-funny-comments.sql

Vuelva a cambiarlos con el comando:

shell> replace " #" " --" -- text-file-with-funny-comments.sql

1.7.6. Cómo trata MySQL las restricciones (Constraints)

MySQL le permite trabajar con tablas transaccionales, que permiten hacer un rollback, y con tablas no transaccionales que no lo permiten. Es por ello que las restricciones son algo distintas en MySQL respecto a otras bases de datos. Debemos tratar el caso en el que se insertan o actualizan muchos registros en una tabla no transaccional en la que los cambios no pueden deshacerse cuando ocurre un error.

La filosofía básica es que MySQL Server trata de producir un error para cualquier cosa que detecte mientras parsea un comando que va a ejecutarse, y trata de recuperarse de cualquier error que ocurra mientras se ejecuta el comando. Lo hacemos en la mayoría de casos, pero todavía no en todos.

Las opciones en MySQL cuando ocurre un error son parar el comando en medio de la ejecución o recuperarse lo mejor posible del problema y continuar. Por defecto, el servidor utiliza esta última opción. Esto significa, por ejemplo, que el servidor puede cambiar algunos valores ilegales por el valor legal más próximo.

A partir de la versión 5.0.2 de MySQL, hay disponibles varios modos SQL para proporcionar un mayor control sobre cómo aceptar valores incorrectos y si continuar ejecutando el comando o abortarlo cuando ocurre el error. Usando estas opciones, puede configurar MySQL Server para actuar en un modo más tradicional como otros servidores de bases de datos que rechazan datos incorrectos. Los modos SQL pueden cambiarse en tiempo de ejecución, lo que permite a los clientes individuales seleccionar el comportamiento más apropiado para sus requerimientos. Consulte Sección 5.3.2, “El modo SQL del servidor”.

La siguiente sección describe qué ocurre para diferentes tipos de restricciones.

1.7.6.1. Restricciones (constraints) en los índices y

Normalmente, un error ocurre cuando trata de ejecutar un o en un registro que viole la clave primaria, clave única o clave foránea. Si usa un motor transaccional como , MySQL automáticamente deshace el comando. Si usa un motor no transaccional, MySQL para de procesar el comando en el registro en el que ocurre el error y deja sin procesar el resto de registros.

Si desea ignorar este tipo de violaciones de claves, MySQL permite la palabra clave para y . En este caso, MySQL ignora cualquier violación de clave y continúa procesando el siguiente registro. Consulte Sección 13.2.4, “Sintaxis de . See Sección 13.2.10, “Sintaxis de .

Puede obtener información acerca del número de registro insertados o actualizados realmente con la función de la API de C . Consulte Sección 24.3.3.32, “. A partir de MySQL 4.1 puede usar el comando . Consulte Sección 13.5.4.22, “Sintaxis de .

De momento, sólo las tablas soportan claves foráneas. Consulte Sección 15.6.4, “Restricciones (constraints) . El soporte para claves foráneas para tablas está previsto para implementarse en MySQL 5.1.

1.7.6.2. Restricciones (constraints) sobre datos inválidos

Antes de la versión 5.0.2 de MySQL, se permitía insertar valores ilegales convirtiéndolos en valores legales. A partir de la versión 5.0.2, sigue este compartimiento por defecto, pero puede elegir un tratamiento para valores incorrectos más tradicional, como no aceptarlos y abortar los comandos que los incluyen. Esta sección describe el comportamiento por defecto de MySQL (permisivo), así como el nuevo modo estricto SQL y en qué se diferencian.

Lo siguiente es cierto si no usa modo estricto. Si inserta un valor "incorrecto" en una columna, como en una columna o una valor numérico demasiado grande en una columna numérica, MySQL cambia el valor al "mejor valor posible" para la columna en lugar de producir un error:

  • Si trata de almacenar un valor fuera de rango en una columna numérica, MySQL Server en su lugar almacena cero, el menor valor posible, o el mayor valor posible en la columna.

  • Para cadenas de carácteres, MySQL almacena una cadena vacía o tanto de la cadena de carácteras como quepa en la columna.

  • Si trata de almacenar una cadena de carácteres que no empiece con un número en una columna numérica, MySQL Server almacena 0.

  • MySQL le permite almacenar ciertos valores incorrectos en columnas y (tales como o ). La idea es que no es el trabajo del servidor SQL validar fechas. Si MySQL puede almacenar una fecha y recuperarla fielmente, se almacena tal y como se da. Si la fecha es totalmente incorrecta (más allá de la capacidad del servidor para almacenarla), se almacena en su lugar el valor especial .

  • Si intenta almacenar en una columna que no admita valores ocurre un error para los comandos de un solo registro. Para comandos de varios registros o para comandos , MySQL Server almacena el valor implícito para el tipo de datos de la columna. En general, es para tipos numéricos, cadena vacía () para tipos de cadenas de carácteres, y el valor "cero" para tipos de fecha y tiempo. Los valores implícitos por defecto se discuten en Sección 13.1.5, “Sintaxis de .

  • Si un comando no especifica un valor para una columna, MySQL inserta su valor por defecto si la columna especifica un valor mediante la cláusula . Si la definición no tiene tal cláusula clause, MySQL inserta el valor por defecto implícito para el tipo de datos de la columna.

La razón para las reglas anteriores es que no podemos validar esas condiciones hasta que los comandos han empezado a ejecutarse. No podemos deshacer si encontramos un problema tras actualizar algunos registros, ya que el motor de almacenamiento puede no soportar rollback. La opción de terminar el comando no es siempre positiva; en este caso, la actualización quedaría "a medias", lo que posiblemente es la peor opción. En este caso, lo mejor es hacerlo "lo mejor posible" y continuar como si nada hubiera ocurrido.

A partir de MySQL 5.0.2, puede seleccionar un tratamiento de validación de datos de entrada más estricto usando los modos SQL o . Consulte Sección 5.3.2, “El modo SQL del servidor”.

funciona así:

  • Para motores de almacenamiento transaccionales, valores incorrectos en cualquier parte del comando provocan que se aborte el comando y se deshaga el mismo.

  • Para motores no transaccionales, el comando aborta si ocurre un error en el primer registro a insertar o actualizar. (En este caso, el comando dejará la tabla intacta, igual que en una tabla transaccional.) Los errores en registros después del primero no abortan el comando. En lugar de ello, los valores incorrectos se ajustan y se generan advertencias en lugar de errores. En otras palabras, con , un valor incorrecto provoca que MySQL deshaga todas las actualizaciones hechas hasta el momento, si es posible.

Para chequeo estricto, active . Es equivalente a excepto que en motores de almacenamiento no transaccionales, los errores abortan el comando incluso cuando hay datos incorrectos a partir del primer registro. Esto significa que si ocurre un error a medias de una inserción o actualización de varios registros en una tabla no transaccional, se produce una actualización parcial. Los primeros registros se insertan o actualizan, pero aquéllos a partir del punto en que ocurre el error no. Para evitar esto en tablas no transaccionales, use inserciones de un solo registro o use para obtener advertencias en lugar de errores. Para evitar problemas, no utilice MySQL para validar contenido de columnas. Es preferible (y a menudo más rápido) dejar que la aplicación se asegure de pasar sólo valores legales a la base de datos.

Con cualquiera de las opciones de modo estricto, puede hacer que se traten los errores como advertencias usando o en lugar de o sin .

1.7.6.3. Restricciones y

Las columnas y proporcionan una manera eficiente de definir columnas que contienen un conjunto dado de valores. Sin embargo, antes de MySQL 5.0.2, y no son restricciones reales. Esto es por la misma razón que tampoco lo es. Consulte Sección 1.7.6.2, “Restricciones (constraints) sobre datos inválidos”.

Las columnas de tipo siempre tienen un valor por defecto. Si no especifica un valor por defecto, entonces será para las columnas que permitan valores , si no, se utiliza el primer valor de la enumeración como valor por defecto.

Si inserta un valor incorrecto en una columna o si fuerza insertar un valor en una columna con , se inicializa al valor reservado para enumeraciones , el cual se muestra como una cadena vacía en un contexto de cadenas de carácteres. Consulte Sección 11.4.4, “El tipo de columna .

Si insertar un valor incorrecto en una columna , se ignora el valor incorrecto. Por ejemplo, si la columna puede contener los valores , , y , un intento de insertar resulta en un valor de . Consulte Sección 11.4.5, “El tipo .

En MySQL 5.0.2, puede configurar el servidor para que use el modo estricto de SQL. Consulte Sección 5.3.2, “El modo SQL del servidor”. Cuando el modo estricto está activado, la definición de columnas o no actúa como una restricción en valores insertados en la columna. Los valores que no satisfacen estas condiciones provocan un error:

  • Un valor debe elegirse entre los listados en la definición de la columna, o el equivalente numérico interno. El valor no puede ser un valor de error (esto es 0 o la cadena vacía). Para una columna definida como , valores tales como , , y son ilegales y rehusados.

  • Un valor debe ser una cadena vacía o un valor consistente en uno o más valores listados en la definición de la columna separados por comas. Para una columna definida como , valores tales como , y serían ilegales y, por lo tanto, rehusados.

Se pueden suprimir los errores derivados de valores inválidos en modo estricto usando o . En ese caso, se genera una advertencia en lugar de un error. Para tipos , el valor se inserta como un miembro erróneo (). Para tipo , el valor se inserta igual excepto que se borra cualquier subcadena inválida. Por ejemplo, se convertiría en , como se ha descrito.