Página 1 de 2

ERROR: invalid input syntax for integer en PostgreSQL

NotaPublicado: 2021-10-19 14:34 @648
por seafree
¿Qué tal? Buenas tardes. Agradeceré su apoyo para importar valores negativos en PostgreSQL. El mensaje es el siguiente:

ERROR: invalid input syntax for integer: "-219.204" in PostgreSQL

El campo valor, donde se almacenan los valores fue creado de tipo integer.

En espera de su apoyo, saludos.

Re: ERROR: invalid input syntax for integer

NotaPublicado: 2021-10-19 14:45 @656
por explorer
Pero... ¿en qué localización está trabajando? Es posible que el carácter "." sea el que está dando problemas...

Re: ERROR: invalid input syntax for integer

NotaPublicado: 2021-10-20 12:15 @552
por seafree
¿Qué tal, explorer? Verás lo que necesito es importar los siguiente datos:
Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
TMD,01/01/2021 12:01:12 a.m.,-219.113
TMD,01/01/2021 12:05:38 a.m.,-219.204
TMD,01/01/2021 12:09:21 a.m.,-218.779
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4

La tabla que creé para importar el archivo la definí como:
Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
Column |         Type         | Modifiers
--------+----------------------+-----------
 sub    | character varying(5) |
 fecha  | character(40)        |
 valor  | numeric(6,2)         |
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4

Como podrás observar la columna fecha la definí como carácter porque no hallé la forma de definirla en PostgreSQL donde acepte el a.m. y p.m.; resulta algo absurdo utilizar el AM y PM pero los debo de manipular así porque son datos importados.

¿Me podrás brindar alguna idea? Gracias y saludos.

Re: ERROR: invalid input syntax for integer

NotaPublicado: 2021-10-20 12:23 @557
por seafree
SOLUCIONADO, GRACIAS Y SALUDOS

Re: ERROR: invalid input syntax for integer

NotaPublicado: 2021-10-20 12:36 @567
por seafree
Lo siento, lo olvidaba: logré importarlo PERO el campo fecha quedo definido como:

fecha character(40)

¿Existe la posibilidad de guardar el campo fecha como timestamp o cual es el tipo de dato que permite guardarlo con a.m. y p.m.?

Gracias.

Re: ERROR: invalid input syntax for integer

NotaPublicado: 2021-10-20 15:19 @680
por explorer
Claro que sí.

La documentación de PostgreSQL dice que si el dato que estamos leyendo no coincide con alguno de los tipos de datos que los campos reconocen de forma directa se pueden usar funciones de formateo como to_date() o to_timestamp() para ayudar en la interpretación del dato.

Por ejemplo, si tenemos '01/01/2021 12:01:12 a.m.' como dato de entrada, podemos usar to_timestamp('01/01/2021 12:01:12 a.m.', 'DD/MM/YYYY HH:MI:SS A.M.') para la entrada de la marca de fecha en el INPUT de la consulta.

Ahora bien... como también pone en la documentación, en ocasiones se puede intentar hacer un preformateo (en este caso, en Perl), para pasar de '01/01/2021 12:01:12 a.m.' a un formato reconocido directamente. O sea, el trabajo que haría to_timestamp(), hacerlo con Perl, y el resultado pasarlo directamente a la base de datos.

En tu caso, el problema se reduce a detectar que si estás en una hora p.m., le sumarías 12 a la cifra de la hora. Esto lo puedes hacer con una expresión regular y una condición.

Algo así:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. $dato = "01/01/2021 03:01:12 p.m.";
  2. say "Dato:      $dato";
  3. my @fecha = $dato =~ m{(\d+)/(\d+)/(\d+) (\d+):(\d+):(\d+) ([ap])[.]m[.]}i;
  4. say "Leido:    [@fecha]";
  5. $fecha[3] += 12*(lc($fecha[-1]) eq "p");
  6. printf "Resultado: %04d-%02d-%02d %02d:%02d:%02d\n", @fecha[2,1,0,3,4,5];
Coloreado en 0.003 segundos, usando GeSHi 1.0.8.4

Re: ERROR: invalid input syntax for integer en PostgreSQL

NotaPublicado: 2021-10-21 08:24 @391
por seafree
Gracias, explorer. Saludos.

Re: ERROR: invalid input syntax for integer en PostgreSQL

NotaPublicado: 2021-12-02 11:03 @502
por seafree
Algo tarde pero he regresado, discúlpame por favor, explorer. ¿Me podrás proporcionar algunos referencias sobre las expresiones regulares? No entiendo muy bien el ejemplo que muestras.

Hablando en especifico de la EXPRESION REGULAR:

my @fecha = $dato =~ m{(\d+)/(\d+)/(\d+) (\d+):(\d+):(\d+) ([ap])[.]m[.]}i;

Arroja el resultado: 0000-00-00 00:00:00

La expresion regular no se ejecuta.

Que esta pasando?

Ayuda por favor.

Re: ERROR: invalid input syntax for integer en PostgreSQL

NotaPublicado: 2021-12-02 11:53 @537
por explorer
Aprender expresiones regulares no es fácil, pero por fortuna, con lo básico, se pueden hacer cosas muy potentes.

Perl, además, es el lenguaje que mejor uso hace de ellas, y que posee más potencia en sus patrones de búsqueda y sustitución. Es una de las partes fundamentales del lenguaje Perl, junto con CPAN y su comunidad.

En la documentación Perl encontrarás un montón de documentación sobre expresiones regulares. Tanto, que abruma.

Este es un listado de esos documentos, que muy posiblemente ya les tengas instalados en tu ordenador y que podrás consultarlos con el comando perldoc. Si quieres leerlos en español, puedes pulsar en los siguientes enlaces.

  • perlre - Manual sobre expresiones regulares en Perl
  • perlrebackslash - Secuencias de escape en expresiones regulares en Perl
  • perlrecharclass - Clases de caracteres en expresiones regulares Perl
  • perlrequick - Guía rápida de las expresiones regulares
  • perlreref - Referencia de expresiones regulares en Perl. Algo así como una tarjeta de referencia rápida
  • perlretut - Tutorial de expresiones regulares
  • perlfaq6 - Preguntas más frecuentes sobre expresiones regulares
Empieza con perlrequick, y luego pasas a perlfaq6 y perlretut, para terminar en perlre.

En estos foros encontrarás muchos cientos de ejemplos de problemas resueltos de forma rápida con la ayuda de las expresiones regulares.

En cuanto a la duda que tienes creo que te refieres a entender qué hace la línea 3 del código.

my @fecha = $dato =~ m{(\d+)/(\d+)/(\d+) (\d+):(\d+):(\d+) ([ap])[.]m[.]}i;

Esa línea es una asignación (=) a un array (@fecha), así que esperamos que la parte derecha de la asignación nos devuelva una lista de valores.

La parte derecha es una expresión regular:

$dato =~ m{(\d+)/(\d+)/(\d+) (\d+):(\d+):(\d+) ([ap])[.]m[.]}i;

Se usa el operador "=~" para aplicar la operación que hay a la derecha, a la cadena de caracteres que está almacenada en $dato. La operación es de búsqueda ("m", de match). Eso quiere decir que queremos buscar dentro de $dato algo que coincida con el patrón que está entre los delimitadores (las llaves {}). Además, la búsqueda queremos hacerla independientemente de si está en mayúsculas o minúsculas (la "i" del final).

El patrón es este: (\d+)/(\d+)/(\d+) (\d+):(\d+):(\d+) ([ap])[.]m[.] Lo que buscamos debe coincidir con él.

Aquí hay que decir que los patrones forman su propio lenguaje: algunos caracteres son literales pero otros tienen un significado especial. Por ejemplo, los paréntesis tienen la misión de "capturar" (guardarnos) aquello que coincida con el patrón que está dentro de ellos. Así, "(\d+)" quiere decir que queremos quedarnos con uno o más (+) dígitos (\d).

Entonces, con la primera parte del patrón, (\d+)/(\d+)/(\d+) (\d+):(\d+):(\d+), estamos buscando: un número, seguido del carácter "/", seguido de otro número, seguido del carácter "/", seguido de otro número, seguido de un espacio en blanco, y sigue lo mismo con números separados con caracteres ":". O sea, que dentro de $dato estamos buscando fechas así: 01/01/2021 12:01:12. Y todos los números nos los vamos "guardando", por acción de los paréntesis.

Con la segunda parte del patrón, ([ap])[.]m[.], queremos buscar o coincidir con:
  • ([ap]) - una letra, bien sea la "a" o la "p" (los corchetes forman una "clase de caracteres"); esa letra es guardada
  • [.]m[.] - lo que sigue debe coincidir con: un punto, la letra "m", y otro punto; los puntos deben ir entre corchetes o escapados con "\" porque tienen un significado para las exp. reg., y no queremos eso, sino que buscamos un punto (literal)
Esta parte, entonces, está buscando por "a.m." o "p.m." (recordar que no nos importa si está en mayúsculas). Y la letra principal ("A" o "P") nos la guardamos.

Si... dentro de $dato, hay una combinación de caracteres que coincide con todo el patrón, el resultado será lo que hayamos almacenado en los paréntesis. Así que... @fecha almacenará
  • los números de la fecha
  • los números de la hora
  • la letra "a" o "p"
(Si $dato no coincidiese, @fecha no contendrá ningún valor).

En la línea 5, le sumamos 12 a la cantidad de horas ($fecha[3]) si la letra que encontramos era una "p" (o "P", de ahí el lc()).

Queda, finalmente, la línea 6, donde vamos sacando de @fecha todos los valores en el orden que queremos, y se lo pasamos a printf() para que lo formatee y lo muestre bonito.

Re: ERROR: invalid input syntax for integer en PostgreSQL

NotaPublicado: 2021-12-02 12:19 @555
por seafree
Enormes Gracias Explorer, explicación excelente, ahora lo pondré en práctica.

Todo funcionará como siempre.

Saludos y Respetos.
seafree