Página 1 de 2

Script con el prompt de windows

NotaPublicado: 2008-07-28 06:26 @310
por miguialberto
Hola,

A ver si alguien me puede ayudar con esta duda que tengo a la hora de escribir un script:

Tengo una base de datos Sybase en la que quiero realizar unas operaciones cada noche (borrado de datos en ciertas tablas). Lo que quiero es ejecutar un script en Perl para que cada noche me realice este trabajo. La manera de realizar esto de manera manual es abrir la shell de Windows (cmd.exe) y alli realizar una llamada a la BD mediante "isql -Login y _pass". En este momento se ejecuta la consola de la BD y allí se puede ordenar lo que se desee.

Estoy intentando escribir el script, pero ando bastante perdido. He probado con System() y Exec() pero solo consigo que se ejecute la shell de Windows (ejecuto cmd.exe). Lo que me falta es la manera de poder comunicarme con la shell, para poder mandarle comandos y yo poder recibir las respuestas que me da para poder procesarlas.

No se si debo usar alguna librería de Win32:: ?? o se puede hacer esto como si se tratara de un fichero y escribir y leer directamente... ¡no sé por dónde empezar a mirar!

Muchas gracias de antemano!

Ciao

NotaPublicado: 2008-07-28 06:56 @330
por explorer
Bienvenido a los foros de Perl en Español, miguialberto.

¿No es posible pedirle a isql que ejecute un fichero sql externo?

Es decir: tu, desde Perl, ejecutas un script que lo que hace es llamar a isql con los parámetros de login y contraseña Y un fichero sql a ejecutar.

Estaba mirando para ver si había algún driver de Sybase para Windows, pero me parece que esa base de datos ha caído en el olvido, y hace mucho que no sale una versión estable (al menos para Windows).

En estos foros hay algunos hilos al respecto de Sybase. Usa el sistema de búsqueda.

NotaPublicado: 2008-07-28 07:12 @341
por miguialberto
Hola,

Muchas gracias por la respuesta y por la rapidez. Voy a intentar mirar lo que me has dicho a ver si encuentro algún "atajo" con Sybase.

De todas formas me gustaría saber cómo se podría hacer en Perl lo que preguntaba anteriormente, el mantener una comunicación bidireccional con la shell o prompt de Windows. ¡Me vale con que me mostréis el camino! (es con fichero redireccionando la entrada, o system() o fork(), o librerías especiales...).

Gracias de nuevo.

Ciao

NotaPublicado: 2008-07-28 08:05 @378
por kidd
Hola migialberto:

Igualmente te doy la bienvenida a los foros de Perl en Español.

Para lo que quieras hay varios módulos en CPAN y quizá el que te recomendaría yo para que comiences es el IO::Prompt.

Saludos

NotaPublicado: 2008-07-28 08:31 @397
por miguialberto
Gracias, lo miraré a ver si me sirve.

De todas formas, tal como comento explorer, en Sybase existe una forma sencilla de cargar un fichero que contenga instrucciones para la BD (select * from table_x; go). Simplemente, cuando se abre la consola con el comando "isql" además de pasarle el User y el pass se le puede pasar un archivo de lectura y otro de salida. El archivo input o de entrada se pone después de poner "-i" y el de output o salida después de poner "-o".

Por ejemplo, para el user "Guess" con password "secret" y con un fichero llamado "Script_Sybase" que está en "C:/" y que los resultados queremos los deje en "C:/result", tendríamos que escribir:

Código: Seleccionar todo
isql -U Guess -P secret -i c:/Script_Sybase -o C:/result


También he visto que se puede acceder a la BD a través del puerto que esté escuchando... ¡ya os contaré en este post lo que vaya averiguando!

Saludos y gracias de nuevo.

NotaPublicado: 2008-07-28 09:01 @418
por explorer
Pues entonces, solo te queda meter esa línea en un system().

Atención: si pones algún carácter '\', debes escaparlo (cosas de Windows).

NotaPublicado: 2008-07-29 03:57 @206
por Jenda
Otra opción es olvidar isql y conectar a la base de datos directamente desde Perl usando DBI y DBD::ODBC. Y mandar los queries a la BD desde el script Perl.

NotaPublicado: 2008-07-29 04:38 @234
por explorer
¡Anda, mira! ¡Pero si eso es justo lo que he usado todo el año pasado, y no me acordaba!

Yo usaba eso con la base de datos Informix. Aunque sí que existe el driver DBD::Informix (servido por la propia IBM), en el lugar de trabajo donde estaba usábamos la pasarela ODBC. Un poco lenta (sobre todo cuando haces peticiones de decenas de millones de registros) pero al menos daba una solución conocida.

NotaPublicado: 2008-07-29 05:19 @263
por miguialberto
¡Gracias por dar más posibilidades!

De momento me he creado un programa que escribe todas las instrucciones que quiero ejecutar en Sybase en un archivo y luego llamo al comando de "isql" que escribe en el anterior post. Por si le interesa a alguien, aquí dejo el código:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
use Date::Calc qw( Time_to_Date );  #($year,$month,$day, $hour,$min,$sec) = Time_to_Date([time]);

open (INPUT_FILE, '>c:/data.txt');

my @current_date = Time_to_Date(time);
my $db_command = "use pubs2\ngo\nselect *\nfrom authors\ngo\nquit";

print INPUT_FILE $db_command;

close (INPUT_FILE);

my $output_file_path = "c:/Log_".$current_date[2]."_".$current_date[1]."_".$current_date[0].".txt";
system('isql -U sa -P -i c:/data.txt -o '.$output_file_path);
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4


El script guarda la consulta en C:/data.txt. A este archivo se le pasa como parámetro a Sybase cuando se inicializa. Los resultados los deja en C:/Log_<fecha_actual>. Además, este script se puede ejecutar en un BD Sybase que tenga instalada la BD de ejemplo "pubs2", que viene por defecto con la documentación.

¡Gracias de nuevo por la ayuda!

Ciao

NotaPublicado: 2008-07-29 06:31 @313
por explorer
Otra posibilidad (no probada):

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
#!/usr/bin/perl
use strict;
use warnings;
use diagnostics;

my $fichero_entrada = 'C:/data.txt';
open (INPUT_FILE, ">$fichero_entrada");
print INPUT_FILE join "\n", 'use pubs2', 'go', 'select *', 'from authors', 'go', 'quit';
close INPUT_FILE;

my @current_date     = localtime();
my ($dia,$mes,$anno) = ($current_date[3], $current_date[4]++, $current_date[5]+1900);

my $fichero_salida = sprintf "C:/Log_%02d_%02d_%04d.txt ", $dia, $mes, $anno;

system("isql -U sa -P -i $fichero_entrada -o $fichero_salida");

__END__
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
Te ahorras un módulo.

Un detalle: yo preferiría cambiar el orden de la fecha, para que sea en el orden año, mes, día. Así:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
my $fichero_salida = sprintf "C:/Log_%04d_%02d_%02d.txt ", $anno, $mes, $dia;
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

De esa forma, los ficheros podrán ser ordenados temporalmente por su nombre, independientemente de su fecha de modificación, algo muy útil cuando esa fecha se pierde al mover los ficheros de un sistema de ficheros a otro.