Históricamente, MySQL siempre ha privilegiado la tolerancia al error antes que el rigor de los datos. Esta elección condujo poco a poco a una gestión permisiva de fechas y horas: aceptación de valores inválidos (0000-00-00, mes o día a cero), conversiones implícitas silenciosas, o incluso sustitución automática de valores faltantes. Debido a esta naturaleza históricamente permisiva del motor MySQL, estas prácticas no provocaban errores bloqueantes, sino simples advertencias, a menudo ignoradas por los desarrolladores a nivel de la capa aplicativa ASP. Después de todo, mientras funcione...
Esta permisividad tiene consecuencias duraderas, tanto sobre los datos como sobre el rendimiento necesario para acceder a ellos, e incluso sobre su calidad. Numerosos esquemas fueron diseñados para apoyarse en "fechas centinela" (0000-00-00 00:00:00) supuestamente destinadas a representar la ausencia de valor, en lugar de utilizar el único valor fiable: NULL.
La consecuencia es que muchas interfaces y conectores cliente (ODBC, PHP, etc.) tuvieron que implementar comportamientos específicos para gestionar estas pseudofechas incorrectas, ya sea transformándolas o generando errores de ejecución. Más allá de la no conformidad técnica, estos valores plantean de forma más frontal la verdadera cuestión de su naturaleza: ¿significan "desconocido", "no aplicable", "error" o "valor real"? Ahora bien, un dato cuya calidad no puede determinar es por esencia inexplotable, por tanto inútil de almacenar. Esto va totalmente en contra del hecho mismo de almacenarlo en una base.
MySQL intentó corregir con el tiempo estas derivas originales introduciendo modos SQL estrictos (sql_mode), restricciones CHECK realmente aplicadas, y una mejor conformidad con el estándar SQL. Sin embargo, estos mecanismos siguen siendo opcionales y llegaron tardíamente, dejando de facto una situación con muchas bases en producción que todavía mezclan comportamientos heredados (modos permisivos, datos históricos inválidos) con expectativas modernas de robustez.
MariaDB, por su parte, aprendió de los errores de MySQL y optó por mostrarse mucho más fiable y conforme con los estándares SQL, ofreciendo al mismo tiempo cierta permisividad bajo demanda para casos particulares, con el fin de poder operar transiciones graduales sobre bases de datos y bases de código fuente importantes.
Este artículo le proporciona técnicas de contorno eficaces para gestionar los casos más delicados, así como buenas prácticas tales como la definición de esquemas estrictos, el rechazo de fechas inválidas en la escritura, la lectura fiable de fechas incorrectas, el uso correcto de NULL, o incluso una configuración coherente del servidor y de los clientes, es decir, el Driver ODBC que sirve para proporcionar los datos a su aplicación ASP Classic.
Empiece con una respiración profunda: en la inmensa mayoría de los casos, si su esquema y sus datos son correctos, su código ASP Classic se comportará de manera idéntica con su base MariaDB que con MySQL. En caso de duda, puede asegurarse verificando la validez de las comparaciones de fechas (ej. >=) en algunas de sus consultas SQL, dado que MariaDB respeta los tipos de forma más estricta que MySQL.
La mayoría de los errores que puede encontrar surgen generalmente durante la migración de una antigua base MySQL hacia MariaDB. La causa principal en el 98% de los casos: MariaDB rechaza fechas inválidas que MySQL aceptaba hasta entonces (ej. 0000-00-00). MySQL toleró durante mucho tiempo estos datos, aunque fueran inválidos según el estándar SQL.
Su aplicación ASP Classic funciona bien con su base histórica MySQL, luego la convierte a MariaDB. ¡Y ahí todo explota! Usted culpa a MariaDB y se queja de sus bugs, pero en realidad no es así: las soluciones afortunadamente están cerca y son fáciles. La respuesta eficaz consiste en limpiar sus datos, clarificar el esquema y, a veces, ajustar mínimamente el código aplicativo del lado ASP Classic.
MariaDB no crea el problema, lo expone. En este sentido, dé las gracias a MySQL y a sus prácticas permisivas históricas. Donde usted creyó que le hacía un favor, solo le daba su bendición cuando cometía muy malas acciones con sus datos. Debería haberle advertido, pero prefirió dejarle almacenar fechas incorrectas e inexistentes.
Las malas prácticas heredadas del pasado explican la frecuencia de los bugs relacionados con fechas y horas durante migraciones, importaciones, exportaciones, o simplemente durante el consumo de datos a través de Drivers ODBC modernos y conformes con los estándares.
Esta migración de datos actúa como un revelador de datos históricamente incorrectos, en particular en las fechas. La presencia de estos datos incorrectos le alerta, por consiguiente, sobre los puntos mejorables en su schema y/o en su código ASP.
La gestión sana de fechas y horas en MySQL y MariaDB no es una coquetería, sino una garantía de fiabilidad de su aplicación por una parte, y de los datos que almacena con tanto cuidado por otra.
Los siguientes consejos y buenas prácticas le permiten hacer frente a las situaciones potencialmente bloqueantes más frecuentemente encontradas cuando gestiona fechas en bases MySQL/MariaDB y las explota desde ASP Classic.
ASP Classic no tiene aquí ninguna culpa, tampoco el Driver ODBC MySQL o MariaDB: todos los problemas mencionados dependen en su inmensa mayoría del diseño de la propia base de datos. Una vez corregido su schema y limpiados sus datos históricos, puede dormir tranquilo 🛌.
Esta guía es completa y cubre una multitud de casos: generalmente hay pocas razones para que tenga que aplicarlo todo, y solo algunos de estos consejos bastarán por lo general para resolver los pequeños bugs a los que se enfrenta.
Estamos acostumbrados a los casos particulares y a su servicio para asistirle con su código ASP Classic durante sus migraciones, mejoras o resolución de bugs difíciles.
El punto clave es: Racionalice su schema.
El schema de su base de datos define el conjunto de reglas que serán aplicables durante su explotación en lectura y escritura. Cuanto más completo y reflexionado sea este schema, más previsible será su aplicación y más fiables serán sus datos.
Podrá sortear casi todos estos problemas de rigor y pasar por encima de ellos: nuestro artículo le detalla las posibilidades. Tenga no obstante presente que, aunque esto sea técnicamente funcional, estos contornos solo tienen vocación de ser temporales, porque el problema de fondo subsiste: existen fechas/horas incorrectas en la base, y resolver el problema en origen es su mejor garantía. Querer simplemente sortearlas e ignorarlas le obligará, en caso contrario, a programar muchísimas, demasiadas, verificaciones en ASP Classic para gestionar fechas incorrectas, mientras que la mejor manera de defenderse contra este enemigo es ... no tener que enfrentarse a él en absoluto.
Conformar su base de datos generalmente no es una tarea larga. Una vez limpiadas las fechas y clarificado el esquema, MariaDB resulta mucho más previsible que MySQL, lo que permite a su aplicación ASP Classic ganar en perennidad y, sobre todo, en estabilidad. Y en muchos casos, también en rendimiento.
Cuando define la estructura de su tabla, elija el tipo DATE o DATETIME. Puede elegir TIMESTAMP si necesita explícitamente una gestión automática de la zona horaria.
No almacene jamás una fecha en un campo de tipo VARCHAR, a riesgo de no poder filtrar o comparar sobre esos campos de manera eficaz por una parte, y de ralentizar drásticamente el rendimiento por otra.
Almacenar sus datos de fecha/hora en un campo de tipo VARCHAR es garantía de problemas hoy o mañana. Esto le impide efectuar comparaciones y ordenaciones eficaces, o le obliga a recurrir a la función STR_TO_DATE() de manera sistemática en sus consultas de lectura, lo que degrada enormemente el rendimiento de sus consultas.
Ejemplo de mala práctica:
-- Leer desde el campo "d_date_txt" de tipo VARCHAR.
-- Intentar convertir la cadena en fecha según el patrón indicado.
----- Fallará en el primer dato que no respete el patrón indicado.
SELECT
STR_TO_DATE(d_date_txt, '%Y-%m-%d %H:%i:%s') AS d_date_safe
FROM miTabla;El valor NULL es el único valor por defecto que debe utilizar si no existe ninguna fecha. Es estándar, fiable y resistente al futuro.
Por qué NULL es su nuevo mejor amigo:
STRICT_TRANS_TABLES, NO_ZERO_DATE)Ejemplo de buena práctica:
-- Creación de tabla
-- Utilizar un valor NULL por defecto => Válido en MySQL y MariaDB
CREATE TABLE contactRequests (
d_dateReceived DATETIME NULL DEFAULT NULL
);Cuando un campo está destinado a contener siempre la fecha de adición o de última actualización, es inútil calcular y construir la fecha actual en su código ASP: delegue esta tarea al motor MySQL/MariaDB definiendo el valor por defecto de su campo como CURRENT_TIMESTAMP. De esta manera, se utilizará la fecha actual como valor en el momento de la inserción (INSERT INTO) o de la actualización (UPDATE).
Ejemplos de definición en su schema:
-- Creación de tabla
CREATE TABLE contactRequests (
d_dateReceived DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
);
-- Modificación de una tabla existente
ALTER TABLE contactRequests MODIFY d_dateReceived DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP;En el momento de escribir en su tabla, deberá proporcionar explícitamente CURRENT_TIMESTAMP como valor para este campo, o bien omitir completamente este campo en su consulta y no proporcionar ningún valor: el motor se encargará implícitamente. No especifique NULL, que será rechazado.
Ejemplos en el momento de la escritura:
-- No especificar el campo "d_dateReceived":
-- se rellena automáticamente con la fecha actual.
INSERT INTO contactRequests (s_firstname, s_lastname)
VALUES ('John', 'Duff');
-- Proporcionar explícitamente CURRENT_TIMESTAMP
-- (redundante e innecesario, pero funcional)
INSERT INTO contactRequests (s_firstname, s_lastname, d_dateReceived)
VALUES ('John', 'Duff', CURRENT_TIMESTAMP);
-- Proporcionar explícitamente NULL
-- => ¡PROVOCA UN ERROR!
INSERT INTO contactRequests (s_firstname, s_lastname, d_dateReceived)
VALUES ('John', 'Duff', NULL);
Técnicamente le es posible utilizar '0000-00-00 00:00:00' como fecha por defecto. Al menos eso es lo que MySQL le ha hecho creer hasta hoy. Pero no lo haga (si no, deje de leer este artículo). Las diversas consecuencias negativas que esto implica deben hacerle privilegiar NULL desde todo punto de vista.
Algunas informaciones sobre su enemigo '0000-00-00 00:00:00' son necesarias para convencerle:
sql_mode "estrictos" (ej. NO_ZERO_DATE, NO_ZERO_IN_DATE).OPTION.Ejemplo de mala práctica:
-- Creación de tabla
-- Utilizar una fecha inválida por defecto => históricamente tolerada por MySQL
CREATE TABLE contactRequests (
d_dateReceived DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00'
);Puede hacer que un campo de fecha sea obligatorio, con el fin de prohibir cualquier valor vacío, NULL o por defecto, incluido CURRENT_TIMESTAMP. Para ello debe no definir ningún valor por defecto para este campo, y prohibir NULL.
Su objetivo real es por tanto: « La fecha debe venir de la aplicación ASP, no del esquema ».
Ejemplos de definición en su schema:
-- Crear la tabla
---- d_dateReceived es obligatorio
---- NULL está prohibido
---- no se proporciona ningún valor por defecto
---- toda consulta INSERT/UPDATE debe proporcionar explícitamente d_dateReceived; de lo contrario, fallará
CREATE TABLE contactRequests (
d_dateReceived DATETIME NOT NULL
);
-- Modificar la tabla existente
-- Fallará si una sola fila aún contiene NULL en d_dateReceived => Limpiar la tabla antes.
---- d_dateReceived es obligatorio
---- NULL está prohibido
---- no se proporciona ningún valor por defecto
---- toda consulta INSERT/UPDATE debe proporcionar explícitamente d_dateReceived; de lo contrario, fallará
ALTER TABLE contactRequests
MODIFY d_dateReceived DATETIME NOT NULL;A partir de este momento:
NULL provoca un errorCURRENT_TIMESTAMPEjemplos durante la escritura:
-- Ejemplo sin ningún valor proporcionado:
-- La consulta provoca un error.
INSERT INTO contactRequests (s_firstname, s_lastname)
-- Ejemplo con un valor válido:
-- La consulta es aceptada.
INSERT INTO contactRequests (s_firstname, s_lastname, d_dateReceived)
VALUES ('John', 'Duff', '2026-09-01 14:35:12');
-- Ejemplo de consulta con CURRENT_TIMESTAMP:
-- CURRENT_TIMESTAMP se utiliza aquí como valor explícito y no como valor por defecto.
-- La consulta es aceptada.
INSERT INTO contactRequests (s_firstname, s_lastname, d_dateReceived)
VALUES ('John', 'Duff', CURRENT_TIMESTAMP);Además de hacer obligatorio su campo, puede querer restringir el valor que será aceptado por su campo. Utilice entonces la instrucción SQL CHECK: se aplicará una restricción automática a cada INSERT y UPDATE. Recuerde al respecto que la restricción CHECK es efectivamente aplicada por MariaDB, a diferencia de las versiones antiguas de MySQL. La aplicación de esta restricción supone, por una parte, que ejecute su consulta de creación/alteración de tabla con un sql_mode estricto para evitar inserciones corregidas silenciosamente, y que ya haya limpiado las fechas inválidas de su tabla por otra parte. En general, limpie siempre sus datos antes de modificar su schema, porque este se aplica inmediatamente a los datos ya existentes.
Ejemplos de definición en su schema:
-- Crear la tabla
---- d_dateReceived es obligatorio
---- NULL está prohibido
---- no se proporciona ningún valor por defecto
---- toda consulta INSERT/UPDATE debe proporcionar explícitamente d_dateReceived; de lo contrario, fallará
---- Restricción adicional: Prohíbe las fechas anteriores a 2012
CREATE TABLE contactRequests (
d_dateReceived DATETIME NOT NULL,
CONSTRAINT chk_dateReceived
CHECK (d_dateReceived >= '2012-01-01')
);
-- Modificar la tabla existente
-- Fallará si una sola fila aún contiene NULL en d_dateReceived => Limpiar la tabla antes.
---- d_dateReceived es obligatorio
---- NULL está prohibido
---- no se proporciona ningún valor por defecto
---- toda consulta INSERT/UPDATE debe proporcionar explícitamente d_dateReceived; de lo contrario, fallará
---- Restricción adicional: Prohíbe las fechas anteriores a 2012
ALTER TABLE contactRequests
ADD CONSTRAINT chk_dateReceived
CHECK (d_dateReceived >= '2012-01-01');
Importar su base MySQL en MariaDB es generalmente transparente. Sin embargo, si encuentra un error en un campo de tipo DATE, DATETIME o TIMESTAMP, es porque el motor de MariaDB encuentra fechas incorrectas.
Una fecha inválida no puede existir en una columna DATE/DATETIME si sql_mode es estricto. Algunas técnicas de contorno (ej. ajuste temporal del sql_mode) se presentan aquí para permitirle forzar a MariaDB a importar sus datos "sucios" sin recibir ninguna queja por su parte.
Después, una vez importados sus datos, podrá limpiarlos y terminar ajustando su schema para garantizar la salud de los datos futuros.
El motor MySQL/MariaDB permite aplicar diferentes niveles de rigor. El modo SQL sql_mode está previsto para ello. Puede resultar tentador añadir excepciones al sql_mode durante la conexión ODBC para utilizar o incluso abusar de este modo para "arreglárselas con" datos incorrectos durante la lectura, o "ser laxo" durante la escritura, pero es una muy mala idea.
Este modo SQL debe utilizarse como contorno temporal durante una sesión de importación, antes de finalmente limpiar los datos y racionalizar su schema. Este modo SQL ya no debe utilizarse en producción durante la lectura/escritura mediante el atributo INITSTMT de su cadena de conexión, salvo absoluta necesidad.
El modo SQL puede especificarse de diferentes maneras, con un alcance diferente:
[mysqld]
sql_mode=STRICT_TRANS_TABLES,NO_ZERO_DATE,NO_ZERO_IN_DATESET SESSION sql_mode = 'STRICT_TRANS_TABLES,NO_ZERO_DATE,NO_ZERO_IN_DATE';INITSTMT de su cadena de conexión: este atributo permite al Driver ODBC ejecutar una instrucción SQL al abrir la conexión.<%
'Declarar la cadena de conexión a la base de datos mediante el Driver MariaDB
'(con un sql_mode personalizado)
Dim dbConnString : dbConnString = "Driver={MariaDB ODBC 3.2 Driver}; Server=127.0.0.1; Charset=utf8; Port=3306; Database=dbName_abcdef; User=dbUser_test_abc123; Password=dbPw_abcdef12345; InitStmt={SET SESSION sql_mode='STRICT_TRANS_TABLES,NO_ZERO_DATE,NO_ZERO_IN_DATE';}"
%>SET SESSION sql_mode se ejecuta en cada conexión, y solo está garantizado para esa conexión únicamente. El mayor riesgo es que un pool de conexiones pueda reutilizar una sesión con otro sql_mode. Además, durante una consulta SQL posterior en su código, un SET sql_mode posterior puede sobrescribirlo.Recuerde una vez más que ajustar el modo SQL al nivel más alto, es decir, en su código aplicativo ASP durante su conexión ODBC, está desaconsejado y no necesariamente tiene el alcance suficiente. Este sql_mode está más bien destinado a adaptarse de manera temporal durante sus importaciones de datos, por tanto en las consultas que ejecuta desde phpMyAdmin o desde su software de gestión cliente (ej. HeidiSQL, Navicat, etc.). Una vez importados sus datos (incluidas las fechas históricamente incorrectas), límpielos.
Al término de sus usos del modo SQL con fines de contorno durante sus migraciones, el modo estricto debe privilegiarse de manera global y permanente, y definirse al nivel más bajo, es decir, en el archivo de configuración my.ini en la sección [mysqld].
| Nivel | Método de definición | Ubicación | Alcance real | Impacto | Persistencia | Recomendaciones |
|---|---|---|---|---|---|---|
| 1. Bajo nivel | [mysqld] | my.ini | Global del servidor | Todas las conexiones (después del arranque) | Sí (al reiniciar) | Debe priorizarse en producción para imponer reglas coherentes y evitar conexiones permisivas. |
| 2. Admin | SET GLOBAL sql_mode = ... | SQL ejecutado con privilegios admin (cmd > mysql) | Global del servidor (solo para nuevas conexiones) | Solo nuevas sesiones | No (perdido al reiniciar) | Útil para un cambio inmediato sin editar la configuración [mysqld]. |
| 3. Sesión | SET SESSION sql_mode = ... | SQL ejecutado por aplicación/herramienta (phpMyAdmin, HeidiSQL, etc.) | Sesión actual (una conexión) | Una sola conexión | N/A (vive durante la conexión) | Adecuado para usos puntuales, importaciones, scripts. |
| 4. Aplicativo (alto nivel) | INITSTMT=SET SESSION sql_mode=... | Cadena DSN / conexión ODBC | Sesión actual (en cada apertura de conexión mediante este DSN) | Conexiones que utilizan este DSN | N/A (reaplicado en cada nueva conexión mediante este DSN) | Útil para estandarizar el cliente ODBC. |
ADVERTENCIA: La limpieza de su base de datos implica modificaciones del schema, reemplazos de datos y eliminaciones de registros. Asegúrese antes de cualquier operación de realizar copias de seguridad/backups/DUMP de sus bases de datos. También se recomienda realizarlas en cada una de las etapas importantes de sus operaciones de limpieza. Así podrá volver atrás en caso de error, sin perder sus optimizaciones anteriores.
Tenga en cuenta que las consultas SELECT y UPDATE presentadas a continuación en esta sección solo funcionarán si sql_mode no prohíbe ya las fechas cero en el momento de la ejecución; de lo contrario, la operación fallará.
Después de haber importado sus datos desde MySQL, asegúrese de limpiarlos.
-- El campo d_dateReceived es de tipo Date
-- El umbral 1000-01-01 cubre las fechas técnicamente almacenables,
-- pero inválidas según el estándar SQL.
SELECT *
FROM contactRequests
WHERE d_dateReceived = '0000-00-00 00:00:00'
OR d_dateReceived < '1000-01-01';En este momento le corresponde decidir qué desea hacer con estos datos incorrectos:
NULLUPDATE contactRequests
SET d_dateReceived = NULL
WHERE d_dateReceived = '0000-00-00 00:00:00'
OR d_dateReceived < '1000-01-01';Ahora debe forzar el valor predeterminado a NULL (o CURRENT_TIMESTAMP).
De manera general, limpie siempre sus datos antes de modificar su schema, ya que este último se aplica a los datos ya existentes.
Proporcionar a MySQL/MariaDB fechas limpias y válidas es la garantía de no tener que tratar fechas inválidas en el futuro. Los siguientes consejos le permiten asegurarse de que su código Classic ASP envíe sistemáticamente un valor válido al motor SQL.
En su código Classic ASP, asegúrese de no enviar nunca una cadena vacía a un campo de tipo DATE o DATETIME, sino siempre como mínimo la cadena "NULL", único valor aceptable como valor predeterminado si el schema de su tabla especifica NULL para este campo. Si utiliza una consulta parametrizada ADODB.Command, especifique adDate o adDBTimeStamp como tipo de variable, o proporciónele el tipo variant VBScript Null.
Si desea que se almacene la fecha actual, defina entonces CURRENT_TIMESTAMP como valor predeterminado en el schema de su tabla para este campo. El valor NULL será rechazado a partir de ahora.
<%
'Especificar NULL mediante una consulta SQL clásica
'- - - - - - - - - - - -
strSQL = "INSERT INTO contactRequests (d_dateReceived) VALUES (NULL)"
dbConn.Execute(strSQL)
'Especificar NULL mediante una consulta SQL parametrizada
'- - - - - - - - - - - -
'No utilice vbNull: es una constante de tipo (máscara interna de VBScript)
Set paramCmd = Server.CreateObject("ADODB.Command")
Set paramCmd.ActiveConnection = dbConn
paramCmd.CommandText = "INSERT INTO contactRequests (d_dateReceived) VALUES (?)"
paramCmd.Parameters.Append paramCmd.CreateParameter("@d_dateReceived", adDBTimeStamp, adParamInput, , Null)
paramCmd.Execute
%>La manera más segura de proporcionar una fecha durante su consulta a MySQL/MariaDB es proporcionarle una variable ASP/VBscript de tipo Date, y luego inyectarla en su consulta mediante una consulta parametrizada vía ADODB.Command, forzando explícitamente el tipo ADO a adDate o adDBTimeStamp. El tipo de dato queda así explícito, y no tiene que realizar ninguna conversión ni formateo de la fecha/hora del lado ASP. Las consultas parametrizadas también le protegen contra los riesgos de inyección SQL.
Si no puede utilizar una consulta parametrizada, construya la cadena de fecha que se proporcionará a MySQL/MariaDB en formato ISOYYYY-MM-DD HH:MM:SS, utilizando el siguiente código:
<%
'Devolver una fecha formateada para MySQL/MariaDB en el formato "YYYY-MM-DD HH:MM:SS"
Function DateFormat_MySQL_MariaDB(byVal dtInput)
'Parámetro Variable Tipo Descripción
'--------- -------- ---- -----------
'@param dtInput String/Date Fecha o Fecha/Hora (tipo VBScript/ASP "String" o "Date")
'@return dtOutput String/Null Cadena de fecha formateada "YYYY-MM-DD HH:MM:SS", o bien Null.
Dim sYear, sMonth, sDay, sHour, sMinute, sSecond
Dim dtOutput : dtOutput = Null
'Si la entrada es convertible al tipo "Date"
If (IsDate(dtInput)) Then
'Recuperar las partes de la fecha
sYear = CStr(Year(dtInput))
sMonth = Right("0" & Month(dtInput), 2)
sDay = Right("0" & Day(dtInput), 2)
'Verificar si hay una hora presente
If ((Hour(dtInput) + Minute(dtInput) + Second(dtInput)) > 0) Then
sHour = Right("0" & Hour(dtInput), 2)
sMinute = Right("0" & Minute(dtInput), 2)
sSecond = Right("0" & Second(dtInput), 2)
Else
sHour = "00"
sMinute = "00"
sSecond = "00"
End If
'Construir la cadena de fecha en formato ISO para MySQL/MariaDB
dtOutput = sYear & "-" & sMonth & "-" & sDay & " " & sHour & ":" & sMinute & ":" & sSecond
Else
dtOutput = Null 'Devolver Null si la entrada no es una fecha válida
End If
'Return
DateFormat_MySQL_MariaDB = dtOutput
End Function 'DateFormat_MySQL_MariaDB
'= = = = = = =
'Ejemplos de uso
'= = = = = = =
Dim dateSource, datetimeSource, dateStringForSQL
'Ej. Gestión de una fecha en Inglés
'----------------------------------
SetLocale(1033) 'Configurar el LCID en Inglés
'Definir/leer una fecha de origen (en formato Inglés) – de tipo vbString.
dateSource = "04/13/2026" 'ej. 13 Abril
'Devolver la fecha formateada para MySQL/MariaDB
'=> DEVUELVE: 2026-04-13 00:00:00
dateStringForSQL = DateFormat_MySQL_MariaDB(dateSource)
'Ej. Gestión de una fecha en Francés
'-----------------------------------
SetLocale(1036) 'Configurar el LCID en Francés
'Definir/leer una fecha y hora de origen (en formato Francés) – de tipo vbDate.
datetimeSource = #01/09/2026 14:35:12# 'ej. 1 septiembre
'Devolver la fecha formateada para MySQL/MariaDB
'=> DEVUELVE: 2026-09-01 14:35:12
dateStringForSQL = DateFormat_MySQL_MariaDB(datetimeSource)
'Definir la consulta de inserción en la base de datos
'Utilizar la fecha ya correctamente formateada para MySQL/MariaDB
strSQL = _
"INSERT INTO contactRequests ( " & _
"s_firstname, " & _
"s_lastname, " & _
"d_dateReceived " & _
") VALUES ( " & _
"'John', " & _
"'Duff', " & _
"STR_TO_DATE('" & dateStringForSQL & "') " & _
") "
'Agregar en la base de datos
dbConn.Execute(strSQL)
%>Cuando dispone de una variable ASP/VBScript que no es ni de tipo vbDate ni una cadena vbString que contiene una fecha en formato ISO comprensible por MySQL/MariaDB, debe entonces proporcionar al motor de base de datos indicaciones sobre el formato (pattern) de su fecha, para que la "parse" según este pattern. Puede utilizar diferentes marcadores en su pattern (ej. %Y %m %d %H %i %s etc.).
Esta técnica permite a MySQL/MariaDB saber traducir su cadena de caracteres a una fecha real que podrá almacenar. Para ello, utilice la siguiente función SQL nativa: STR_TO_DATE().
<%
'Definir un datetime con un formato arbitrario/exótico – de tipo vbString.
Dim datetimeSource : datetimeSource = "Ano=2026 Mes=09 Hora=14 Segundo=12 Dia=01 Minuto=35"
'Definir una máscara/patrón que permita a MySQL/MariaDB entender la cadena proporcionada
'(contiene los marcadores %Y %m %d %H %i %s, reconocidos por MySQL/MariaDB)
Dim datetimeMask : datetimeMask = "Ano=%Y Mes=%m Hora=%H Segundo=%s Dia=%d Minuto=%i"
'Definir la consulta de inserción en la base de datos
strSQL = _
"INSERT INTO contactRequests (" & _
"s_firstname, " & _
"s_lastname, " & _
"d_dateReceived " & _
") VALUES (" & _
"'John', " & _
"'Duff', " & _
"STR_TO_DATE('" & datetimeSource & "', '" & datetimeMask & "') " & _
")"
'Agregar en la base de datos
dbConn.Execute(strSQL)
%>Tenga en cuenta, no obstante, que aquí depende de un formato fijo: la mínima variación en la cadena hará fallar su consulta, debido a que STR_TO_DATE() no la comprenderá. Esta técnica le expone fuertemente a inyecciones SQL si datetimeSource u otros valores se vuelven dinámicos. Prefiera siempre las consultas parametrizadas. Póngase en contacto con nosotros si necesita implementar consultas parametrizadas de manera eficaz en su código fuente ASP; dominamos todas sus sutilezas para implementarlas de la mejor manera.
Si debe almacenar la fecha actual en el momento de la inserción (INSERT INTO) o de la actualización (UPDATE), apóyese en el valor predeterminado de su campo. Esto le evita tener que construir la fecha en su código ASP: delega esta tarea al motor MySQL/MariaDB.
Consulte esta sección para implementar esta técnica.
Leer las fechas desde una base MySQL/MariaDB parece ser una operación simple. Sin embargo, según si su base contiene eventualmente fechas históricamente incorrectas, o si desea leerlas según un formato particular, hay que considerar ciertas precauciones y técnicas.
Toda creación de consulta SQL desde su código ASP comporta un riesgo importante de inyección SQL si concatena cadenas, variables y datos, en particular si algunos de estos datos han sido introducidos por un usuario y no están bajo su control.
Para protegerse contra las inyecciones SQL, utilice más bien consultas parametrizadas vía ADODB.Command, especificando cada parámetro en forma de ?. Recuerde forzar el tipo ADO a adDate o adDBTimeStamp en lugar de dejar que ADO adivine: esto limita las conversiones implícitas y los errores silenciosos.
Si tiene dudas sobre la limpieza del schema de la tabla o de los datos que contiene, añada seguridades en sus consultas SQL para evitar tropezar con datos sucios e incorrectos, o devolverlos a su aplicación ASP. Tenga en cuenta que estas prácticas le permiten sortear una fecha inválida, pero ralentizan la ejecución de sus consultas. Limpiar sus datos en origen sigue siendo la mejor práctica.
Estas consultas le permiten por tanto "apañárselas con" datos históricamente incorrectos, pero tienen un coste debido al filtrado que realizan. Constituyen, por ello, un "parche", si no tiene otra opción que tratar datos históricamente sucios e incorrectos, y aún no ha efectuado la limpieza.
-- VARIANTE 1: Más concisa
-- El rendimiento es equivalente entre CASE y NULLIF incluso en grandes cantidades de datos.
-- CAST() no tiene impacto en términos de rendimiento.
-- * * * * *
-- Leer desde el campo "d_date" de tipo DATETIME
-- Asegurarse de que el dato sea una fecha válida
-- Devuelve NULL en caso contrario
SELECT
CAST(
NULLIF(
IF(d_date < '1000-01-01', NULL, d_date),
'0000-00-00 00:00:00'
)
AS DATETIME) AS d_date_safe
FROM contactRequests
-- VARIANTE 2: Más legible
-- El rendimiento es equivalente entre CASE y NULLIF incluso en grandes cantidades de datos.
-- CAST() no tiene impacto en términos de rendimiento.
-- * * * * *
-- Leer desde el campo "d_date" de tipo DATETIME
-- Asegurarse de que el dato sea una fecha válida
-- Devuelve NULL en caso contrario
SELECT
CAST(
CASE
WHEN d_date = '0000-00-00 00:00:00' THEN NULL
WHEN d_date < '1000-01-01' THEN NULL
ELSE d_date
END
AS DATETIME) AS d_date_safe
FROM contactRequestsEl caso más delicado es el de las fechas y horas almacenadas en un campo de tipo VARCHAR. El siguiente código le muestra cómo gestionar este tipo de caso en una cláusula SELECT, pero recuerde que filtrar o comparar sobre estos campos en una cláusula WHERE es casi imposible, y además corre el riesgo de ralentizar drásticamente el rendimiento.
-- Leer desde el campo "d_date_txt" de tipo VARCHAR.
-- Intentar convertir la cadena en fecha según el patrón indicado.
----- Fallará en el primer dato que no respete el patrón indicado.
SELECT
STR_TO_DATE(d_date_txt, '%Y-%m-%d %H:%i:%s') AS d_date_safe
FROM miTabla;Por último, si sus datos están limpios y su schema especifica NULL como valor predeterminado, entonces todas sus líneas son sanas. Su consulta puede entonces ser tan simple y corta como esto:
SELECT d_date FROM miTabla WHERE d_date IS NOT NULLCuando desea leer una fecha según un formato particular, exótico o localizado, puede recurrir a la función DATE_FORMAT() de MySQL/MariaDB, como sigue:
<%
'Se desea recuperar la fecha con el siguiente formato exótico: YYYY/MM hh:ss
' El uso de esta función DATE_FORMAT() ralentiza la consulta.
' Por lo tanto, será más eficiente leer el dato bruto desde MySQL/MariaDB
' y luego utilizar ASP/VBScript para extraer las partes y formatearlo.Dim dateMask : dateMask = "%Y/%m %H:%i"
'Definir la consulta de lectura
Dim strSQL : strSQL = "SELECT DATE_FORMAT(contactRequests.d_dateReceived, '" & dateMask & "') AS myDate FROM contactRequests "
'Abrir la conexión
Set dbConn = Server.CreateObject("ADODB.Connection")
dbConn.Open dbConnString
'Abrir el Recordset en modo "Forward-Only" mediante .Execute()
Set rs = dbConn.Execute(strSQL)
%>En primer lugar, este consejo es temporal. Le es posible desactivar temporalmente los controles estrictos del lado driver mediante el parámetro OPTION en su cadena de conexión, pero tenga en cuenta que esto NO es una solución a largo plazo: solo es un rodeo alrededor de sus datos inválidos.
Sortear (ignorar) los datos inválidos durante la lectura es un parche. El enfoque que debe seguir es el siguiente:
NULL, luego ajustar su schema definiendo NULL como valor predeterminado,Durante una migración de datos desde MySQL hacia MariaDB, MariaDB es más estricto y rechaza la importación de su tabla si contiene fechas vacías 0000-00-00 00:00:00. Sin embargo, si ha forzado su importación pero ha olvidado limpiarlas, entonces esos datos incorrectos aún se encuentran allí.
Cuando su tabla contiene registros con fechas inválidas (ej. 0000-00-00 00:00:00), ADO puede hacerle llegar un mensaje de error procedente del motor MySQL/MariaDB, para quejarse de la presencia de tales fechas vacías. Nuestro mejor consejo en este punto es limpiar sus datos.
Sin embargo, si realmente desea permitir que su aplicación ASP acceda a estos datos, puede entonces utilizar los valores de ciertos Flags en el parámetro OPTION de su cadena de conexión para poder leer desde esta tabla sin encontrar errores del lado ASP. Esto equivale en la práctica a pedir al Driver ODBC que se comporte como MySQL lo hacía históricamente, aunque MariaDB sea más estricto.
Estas opciones deben utilizarse temporalmente para asegurar la compatibilidad de su aplicación Classic ASP con una base de datos que contiene fechas inválidas heredadas de MySQL, pero no deben considerarse una solución definitiva.
Referencias para el parámetro OPTION:
16777216: Autoriza las fechas inválidas (ej. 0000-00-00, 0000-00-00 00:00:00) sin error del lado driver.33554432: Desactiva algunos controles estrictos adicionales sobre las conversiones de fechas y marcas de tiempo.DATETIME NULL),OPTION.Le asistimos con IIS y su código ASP Classic.
Póngase en contacto con nuestro equipo.
NOTA : Sus cambios se aplicarán desde la página siguiente que visitará/cargará.
Al usar este sitio, usted acepta que usemos estadísticas anónimas para analizar nuestro tráfico y mejorar su experiencia de navegación en nuestro sitio, además de tecnologías y cookies para personalizar el contenido. Esta información anónima se puede compartir con nuestros socios de redes sociales y de análisis de confianza.