Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > Noticias
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Grupo de Teaming del ClubDelphi

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 07-02-2008
Avatar de jachguate
jachguate jachguate is offline
Miembro
 
Registrado: may 2003
Ubicación: Guatemala
Posts: 6.254
Poder: 28
jachguate Va por buen camino
Mysql, años bisiestos y divisiones por cero

Al parecer, mySQL tiene problemas con los años bisiestos. Si usas controles Data-Aware o sentencias parametrizadas desde delphi, ¡suerte que delphi te ayuda!, pero si estas construyendo sentencias SQL de puro texto (probablemente para importar datos desde otras fuentes, ¡mucho cuidado!

Este es el resultado de un experimento realizado sobre oracle, PostgreSQL, DB2, firebird y mysql:

Años bisiestos
Oracle:
Código:
SQL> CREATE TABLE leaptest (thedate date);
Table created.

SQL> INSERT INTO leaptest VALUES ('28-feb-2008');
1 row created.

SQL> INSERT INTO leaptest VALUES ('29-feb-2008');
1 row created.

SQL> INSERT INTO leaptest VALUES ('30-feb-2008');
INSERT INTO leaptest VALUES ('30-feb-2008')
*
ERROR at line 1:
ORA-01830: date format picture ends before converting entire input string

SQL> INSERT INTO leaptest VALUES ('29-feb-2007');
INSERT INTO leaptest VALUES ('29-feb-2007')
*
ERROR at line 1:
ORA-01830: date format picture ends before converting entire input string

SQL> SELECT * from leaptest;

THEDATE
---------
28-FEB-08
29-FEB-08
Resultado de la prueba: satisfactorio.

PostgreSQL:
Código:
goods=> CREATE TABLE leaptest (thedate date);
CREATE TABLE
goods=> INSERT INTO leaptest VALUES ('28-feb-2008');
INSERT 0 1
goods=> INSERT INTO leaptest VALUES ('29-feb-2008');
INSERT 0 1
goods=> INSERT INTO leaptest VALUES ('30-feb-2008');
ERROR: date/time field value out of range: "30-feb-2008"
goods=> INSERT INTO leaptest VALUES ('29-feb-2007');
ERROR: date/time field value out of range: "29-feb-2007"
goods=> SELECT * FROM leaptest;
thedate
------------
2008-02-28
2008-02-29
(2 rows)
Resultado de la prueba: satisfactorio.

DB2
Código:
db2 => CREATE TABLE leaptest (thedate date)
DB20000I The SQL command completed successfully.
db2 => INSERT INTO cmihai.leaptest VALUES ('2008-02-28')
DB20000I The SQL command completed successfully.
db2 => INSERT INTO cmihai.leaptest VALUES ('2008-02-29')
DB20000I The SQL command completed successfully.
db2 => INSERT INTO cmihai.leaptest VALUES ('2008-02-30')
DB21034E The command was processed as an SQL statement because it was not a 
valid Command Line Processor command. During SQL processing it returned:
SQL0181N The string representation of a datetime value is out of range.
SQLSTATE=22007
db2 => INSERT INTO cmihai.leaptest VALUES ('2007-02-29')
DB21034E The command was processed as an SQL statement because it was not a
valid Command Line Processor command. During SQL processing it returned:
SQL0181N The string representation of a datetime value is out of range.
SQLSTATE=22007
db2 => SELECT * FROM cmihai.leaptest

THEDATE
----------
02/28/2008
02/29/2008

2 record(s) selected.
Resultado de la prueba: satisfactorio.

Firebird:

Código:
SQL> CREATE TABLE leaptest (thedate date);
SQL> INSERT INTO leaptest VALUES ('28-feb-2008');
SQL> INSERT INTO leaptest VALUES ('29-feb-2008');
SQL> INSERT INTO leaptest VALUES ('30-feb-2008');
Statement failed, SQLCODE = -413
conversion error from string "30-feb-2008"
SQL> INSERT INTO leaptest VALUES ('29-feb-2007');
Statement failed, SQLCODE = -413
conversion error from string "29-feb-2007"
SQL> SELECT * FROM leaptest;

THEDATE
===========
2008-02-28
2008-02-29
Resultado de la prueba: satisfactorio.

MySQL:
Código:
mysql> CREATE TABLE leaptest (thedate date);
Query OK, 0 rows affected (0.00 sec)

mysql> INSERT INTO leaptest VALUES ('28-feb-2008');
Query OK, 1 row affected, 1 warning (0.00 sec)

mysql> INSERT INTO leaptest VALUES ('29-feb-2008');
Query OK, 1 row affected, 1 warning (0.00 sec)

mysql> INSERT INTO leaptest VALUES ('30-feb-2008');
Query OK, 1 row affected, 1 warning (0.00 sec)

mysql> INSERT INTO leaptest VALUES ('29-feb-2007');
Query OK, 1 row affected, 1 warning (0.00 sec)

mysql> SELECT * FROM leaptest;
+------------+
| thedate |
+------------+
| 0000-00-00 |
| 0000-00-00 |
| 0000-00-00 |
| 0000-00-00 |
+------------+
4 rows in set (0.00 sec)
Resultado de la prueba: NO satisfactorio.

Alguién ha indicado que si se usa fechas en formato ISO trabajaría:
Código:
INSERT INTO leaptest VALUES ('2008-02-28');
Esto genera un warning, pero deja la fila con fecha 0000-00-00.
Resultado de la prueba: NO satisfactorio.

División por cero
Oracle
Código:
SQL> SELECT 0/0 FROM dual;
SELECT 0/0 FROM dual
*
ERROR at line 1:
ORA-01476: divisor is equal to zero
Resultado de la prueba: satisfactorio.

PostgreSQL
Código:
goods=> SELECT 0/0;
ERROR: division by zero
Resultado de la prueba: satisfactorio.

DB2:
Código:
db2 => SELECT 0/0 FROM cmihai.leaptest
SQL0801N Division by zero was attempted. SQLSTATE=22012
Resultado de la prueba: satisfactorio.

Firebird:
Código:
SQL> SELECT 0/0 FROM rdb$database;
=====================
Statement failed, SQLCODE = -802
arithmetic exception, numeric overflow, or string truncation
Resultado de la prueba: satisfactorio.

MySQL
Código:
mysql> SELECT 0/0;
+------+
| 0/0 |
+------+
| NULL |
+------+
1 row in set (0.00 sec)
Resultado de la prueba: NO satisfactorio.

Las versiones utilizadas para el experimento son:
DB2 9.5,
Oracle 10g and 11g,
PosgreSQL 8.2, 8.3
Firebird 2
MySQL 5.0.45.

enlace
__________________
Juan Antonio Castillo Hernández (jachguate)
Guía de Estilo | Etiqueta CODE | Búsca antes de preguntar | blog de jachguate
Responder Con Cita
  #2  
Antiguo 07-02-2008
Avatar de lucasarts_18
lucasarts_18 lucasarts_18 is offline
Miembro
 
Registrado: mar 2005
Ubicación: Villa Alemana,Chile
Posts: 1.087
Poder: 21
lucasarts_18 Va por buen camino
Cita:
Empezado por jachguate Ver Mensaje

Alguién ha indicado que si se usa fechas en formato ISO trabajaría:
Código:
INSERT INTO leaptest VALUES ('2008-02-28');
Esto genera un warning, pero deja la fila con fecha 0000-00-00.
Resultado de la prueba: NO satisfactorio.
Esto funciona, ya que la fecha es correcta y está en formato USA , acabo de hacer la prueba en mi mysql y va correcto. Asi tambien si pones

Código:
INSERT INTO leaptest VALUES ('2008-02-29');
y para finalizar...


Código:
INSERT INTO fecha VALUES ('2009-02-29');
Me lo deja en '0000-00-00', pero no me sale ni advertencia ni error, eso es lo malo de mysql . No gestiona muy bien las excepciones.

Hasta Luego .-
__________________
No todo es como parece ser...
Responder Con Cita
  #3  
Antiguo 07-02-2008
keyboy keyboy is offline
Miembro
 
Registrado: oct 2004
Posts: 367
Poder: 20
keyboy Va por buen camino
Hay algunos puntos que observar:

MySQL no acepta fechas en formato 'libre' en una sentencia INSERT como las indicadas. No importa si le ponen 29-feb-2008 o 10-sep-2005, MySQL almacenará 0000-00-00. Es decir, no se trata de un manejo incorrecto de años bisiestos.

Si se introducen fechas en el formato que MySQL entiende, que es el que indica lucasarts_18, las fechas se almacenan correctamente. En la versión 4, según indica el manual:

Cita:
MySQL versions through 4.1 accept certain “illegal” values for dates, such as '1999-11-31'. This is useful when you want to store a possibly incorrect value specified by a user (for example, in a web form) in the database for future processing.
se trata, no de un error, sino de una decisión (buena o mala ya es otra cosa pero es la razón que ellos dan).

No sé en la versión 5 como sea, aunque el manual menciona que debe dar una advertencia. De todas formas, no creo que pueda aducirse que maneja mal las excepciones, simplemente han decidido almacenar valores como 0000-00-00 o NULL (en el caso de 0/0) para valores erróneos. Es una decisión, no un error.

Bye
Responder Con Cita
  #4  
Antiguo 07-02-2008
Avatar de lucasarts_18
lucasarts_18 lucasarts_18 is offline
Miembro
 
Registrado: mar 2005
Ubicación: Villa Alemana,Chile
Posts: 1.087
Poder: 21
lucasarts_18 Va por buen camino
Cita:
Empezado por keyboy Ver Mensaje
se trata, no de un error, sino de una decisión (buena o mala ya es otra cosa pero es la razón que ellos dan).
Tienes razón, es la forma que ellos han optado, sin embargo estoy acostumbrado a un motor como Oracle que no deja pasar ninguna bala..., pero pensando que MySQL se creo para un ambiente web donde lo que importaba era la velocidad, por ahí puede que le encuentre una razón de ser....

Cita:
Empezado por keyboy Ver Mensaje

No sé en la versión 5 como sea, aunque el manual menciona que debe dar una advertencia. De todas formas, no creo que pueda aducirse que maneja mal las excepciones, simplemente han decidido almacenar valores como 0000-00-00 o NULL (en el caso de 0/0) para valores erróneos. Es una decisión, no un error.
A mí no me pasa nada, ninguna advertencia, a veces desde php se me cuelan algunas fechas erroreas, pero ese es otro cuento, puede ser un problema que no lo controle desde el propio php, pero incluso esto, llega a ser un poco incómodo.....

Por último mysql maneja diversos "modos" y pueda que no lo tenga configurado como tal para que me levante tal advertencia, pero esto ya escapa de mis manos, y es que leerme el manual de mysql, que por decirlo de alguna manera "me da un poco de pereza" , empero, prefiero la documentación de php que va directo al grano.

Hasta Luego .-
__________________
No todo es como parece ser...

Última edición por lucasarts_18 fecha: 07-02-2008 a las 18:17:52.
Responder Con Cita
Respuesta



Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro

Temas Similares
Tema Autor Foro Respuestas Último mensaje
El Juego de la X y el 0(Cero). redimido Varios 28 11-08-2007 00:13:19
problemas con divisiones en java lazar JAVA 2 10-04-2007 14:02:49
Cuando cero - cero es 5.755533321E-13 IVAND Firebird e Interbase 4 12-04-2006 16:06:26
division por cero kalimero Varios 7 21-12-2004 16:24:28
Crystal Reports desde cero, cero, cero. Repelus Impresión 1 08-03-2004 21:23:14


La franja horaria es GMT +2. Ahora son las 00:51:42.


Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi
Copyright 1996-2007 Club Delphi