Quien soy? RSS feed Enviar por email Imprimir Parar este menu Ir arriba
Blogzote.com
Mexico, informatica, internet, musica y algo mas…
Pagina 8 de 24« Primera...78910...20...Ultima »

Registros duplicados en Oracle

Como suele pasar, se me olvido crear la llave primaria para una tabla, resultando que se insertaran registros duplicados en ella, ahora, ¿Cómo los elimino? Muy fácil, encontré, rascándole a google, una instrucción estándar para borrar registros duplicados:

1
2
3
4
5
DELETE FROM tabla
 WHERE ROWID NOT IN
            (SELECT MIN(ROWID)
               FROM tabla
              GROUP BY columna1, columna2, columna3...);

Donde por supuesto “tabla” es el nombre de la tabla y “columna1″, “columna2″, etc. Es la llave que identifica a cada registro.

* 22 Comentarios Email Imprimir

Procesar csv en oracle

Esta está facilita, me tope con la necesitad de procesar un archivo csv (comma separated values o valores separados por coma) con utl_file no tuve mayor problema para leer el archivo, ¿pero la cadena (o registro) del archivo, como la leo? Fácil, cree una función a la que se le manda la cadena a procesar y la posición de la columna que deseas y te regresa su valor.

Si tienes por ejemplo la cadena:

1
11111,22222,33333,44444,55555

Necesitas sacar de esa cadena el 3 campo, o sea, el valor “33333″, solo generas la llamada a la función:

1
variable := get_string_value (3,11111,22222,33333,44444,55555);

Aquí les dejo la función:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
--
  -- GET_STRING_VALUE
  --
  -- return the string value for a string id "p_string_id"
  -- in a csv string "p_string"
  -- 
  FUNCTION get_string_value (
     p_string_id            IN      NUMBER,
     p_string               IN      VARCHAR2) 
     RETURN VARCHAR2 IS
 
     v_string_value VARCHAR2(200);
  BEGIN
 
    IF (INSTR(p_string,',') > 0) AND
       (p_string_id         > 0) THEN
       IF p_string_id = 1 THEN
          v_string_value := SUBSTR(p_string, 0, INSTR(p_string,',',1,1)-1);
       ELSE
         IF (INSTR(p_string,',',1,p_string_id-1) > 0) AND
            (INSTR(p_string,',',1,p_string_id)   > 0) THEN			
            v_string_value := SUBSTR(p_string, INSTR(p_string,',',1,p_string_id-1)+1, 
                                              (INSTR(p_string,',',1,p_string_id)-1 - 
                                               INSTR(p_string,',',1,p_string_id-1)));
         ELSIF
            (INSTR(p_string,',',1,p_string_id-1) > 0) AND
            (INSTR(p_string,',',1,p_string_id)   = 0) THEN			
            v_string_value := SUBSTR(p_string, INSTR(p_string,',',1,p_string_id-1)+1, 
                                             (LENGTH(p_string) - 
                                               INSTR(p_string,',',1,p_string_id-1)));
         END IF;
       END IF; 
    END IF;
 
    RETURN v_string_value;
 
  END get_string_value;

Por supuesto no es la única forma de procesar una cadena con valores separados por coma, acá tengo otra forma mediante un loop:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
DECLARE
  v_line      VARCHAR2(1000);
  v_value     VARCHAR2(100);  
  v_index     NUMBER;
BEGIN
  v_line  := '11111,22222,33333,44444,55555';
  v_index := 0;
  FOR i IN 1.. LENGTH(v_line) LOOP
      IF (SUBSTR(v_line, i, 1) = ',') OR
         (LENGTH(v_line)       = i  ) THEN
         --aqui lo que deseas hacer para cada valor 
         --v_value tendra el valor del campo 
         v_value := REPLACE(SUBSTR(v_line, v_index+1, (i-v_index)), ',','');
         v_index := i;
      END IF;
  END LOOP;
END;
* 2 Comentarios Email Imprimir

Llego a cien mil

Después de muchas aventuras, de muchas horas en el, de varios golpes, de una buena lana, de calores y fríos, de muchos lugares conocidos y varios desconocidos, de varios policías queriendo extorsionar, de sufrir en el trafico y gozar a altas velocidades (mientras no nos saque foto el radar), de una subida a un camellón, dos retrovisores rotos, uno que otro rayón, una que otra mujer al volante, una cambio de llantas, varias visitas al mecánico, de ver como la gasolina sube y sube y cada vez se llena con mas dinero, de parrandas, amigos, amigas, niños, subidas, bajadas, de los mil y un topes de la ciudad, de los diez mil y un baches.

Después de todo eso y muchas cosas mas, mi caballo blanco llego a los cien mil kilómetros, parece que fue ayer cuando lo veía con cero kilómetros, era apenas un bebe, como el kilometraje de los coches es como los cumpleaños de nosotros, le escribo esta nota para festejarle, para rendirle tributo a mi “Caballo Blanco”, aunque siendo sinceros ya va siendo hora de pensar en nuevos aires (no le vallan a decir, me valla a fallar por ahí).

100000 kms de mi caballo blanco
Sin comentarios Email Imprimir

Nosotros vs nosotros

El otro día tuve la desfortuna de querer pasar por una zona donde se realizaba una marcha, en esta ocasión fue los trabajadores del IMSS apoyando a los del ISSSTE (apenas me entere que fueron varias mas organizaciones), que marcharon desde el ángel de la independencia hasta el zócalo de la ciudad de México, el resultado no fue mas que unas horas perdidas debido al cierre de algunas arterias y el consecuente trafico ocasionado.

marcha en reforma

No voy a hablar de lo que reclamaba la marcha, seguramente tienen alguna razón valida para hacerlo, no será la primera ni la ultima que se realice, voy a hablar de las marchas en si, de algunas cosas en las que no estoy de acuerdo con ellas.

Para empezar, los mas contentos (o al menos, menos preocupados) de que se realicen las marchas deben de ser los mismos gobernantes, gobernantes causantes del problema, ellos desde su lugar de trabajo agarran, prenden la tele y ven en las noticias que se desarrolla una marcha de tal a cual punto reclamando tal o cual cosa, total, ellos agarran, levantan el teléfono y le marcan a su grupo de granaderos para que los protejan y no pasa de ahí.

Los amolados somos nosotros, haciendo marchas afectándonos a nosotros mismos, con el tiempo perdido, con los negocios que cierran, con el peligro de que un granadero te de un mal golpe, al final no es mas que un nosotros vs nosotros, los granaderos no creo que pertenezcan a la clase política y salgan a defender sus intereses, son iguales a nosotros buscándose el pan de cada día, nada mas que a ellos les pagan por repeler a los demás, y los mas irónico es que les pagan con nuestro dinero, mientras el gobernante desde su sillón solo observa riéndose de cómo nos peleamos entre nosotros, de cómo nos amolamos mas unos a otros, total, el dinero no es suyo, el problema es para nosotros, los jodidos somos nosotros.

Siempre he pensado, ¿Por qué ese grupo de personas, no va directamente a donde este el gobernante? ¿Por qué no va a los pinos, al palacio de gobierno o el lugar donde se encuentre el responsable? Lo saca de los … y le exige que cumpla con su trabajo, trabajo para el cual le estamos pagando (en la mayoría de los casos mucho muy bien pagados), y no lo dejan ir hasta que se encuentre la solución al problema, hasta que haga realmente su trabajo, hasta que cumpla con lo que ofrece o lo que se espera de su cargo.

Sin comentarios Email Imprimir

Oracle UTL_FTP

Hace unos me surgió la necesidad de realizar el paso de algunos archivos planos entre servidores, el problema es que este paso se va a realizar constantemente, entonces tuve que pensar en una solución que fuera fácil, aparte esos archivos no son mas que información que se procesa e ingresa a una tabla de base de datos.

De entrada la solución que se proponía era realizar un shell script para realizar el paso de archivos vía ftp de un servidor a otro, soluciona el problema pero no estaba muy de acuerdo, primero tener que llamar a un shell para después conectarte a Oracle y llamar a un procedimiento, le quita el control a Oracle sobre el manejo de esos archivos, otra era usar directamente UTL_FILE, pero este paquete sirve para el manejo de archivos en el mismo servidor de base de datos, que yo sepa, con utl_file no se puede manejar archivos de otras maquinas.

Tiempo atrás ya había leído de la existencia de un paquete para el manejo de conexiones tcp, el paquete se llama UTL_TCP, suponía entonces que ya debería de existir algo relacionado con el manejo de archivos entre servidores, la opción lógica era buscar el paquete UTL_FTP pero sorpresa, este no existe, bueno y ¿que dice Google al respecto? le di buscar utl_ftp y me regreso varias paginas, me encontré primero con un script guardado en sourceforce llamado “plsqlftp“, pero no me convenció, su desarrollo se ve casi abandonado y no encontré un solo ejemplo de cómo se usa, acabe descartándolo.

Rascándole un poquito mas a los resultados me tope con el que finalmente implemente, le llamaron “FTP Interfase“, me quedo perfecto para lo que necesitaba, se ve bastante robusto y completo, yo solo use tres funciones, “VERIFY_SERVER”, “PUT” y “GET” pero tiene muchas mas, igual más adelante las pueda necesitar, aquí les dejo el procedimiento que generé para realizar los movimientos de archivos:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
  --
  -- MOVE_FILE
  --
  -- move file "p_filename" with ftp interfase, use put or get "p_type_move
  -- "p_type_move" = "PUT" => from "p_localpath" to "p_remotepath"
  -- "p_type_move" = "GET" => from "p_remotepath" to "p_localpath"
  -- use ftp server "p_hostname" with usr "p_username" and pwd "p_password"
  --   
  PROCEDURE move_file    (
     p_type_move           IN      VARCHAR2,
     p_localpath           IN      VARCHAR2,
     p_remotepath          IN      VARCHAR2,
     p_filename            IN      VARCHAR2, 
     p_username            IN      VARCHAR2,
     p_password            IN      VARCHAR2,
     p_hostname            IN      VARCHAR2,
     p_error               OUT     VARCHAR2) IS
 
     v_exception    EXCEPTION;
     p_status       VARCHAR2(32000);
     p_bytes_trans  NUMBER;
     p_trans_start  DATE;
     p_trans_end    DATE;
     dummy          BOOLEAN;
  BEGIN
 
     IF (p_type_move != 'PUT') AND
        (p_type_move != 'GET') THEN
        p_error := 'ERROR: value for p_type_move not supported.';
        RAISE v_exception;
     END IF;
 
     dummy := ftp_interface.verify_server ( 
                    p_remotepath           => p_remotepath,
                    p_username             => p_username,
                    p_password             => p_password,
                    p_hostname             => p_hostname,
                    v_status               => p_status,
                    v_error_message        => p_error,
                    p_port                 => 21,
                    p_filetype             => 'ASCII',
                    p_mainframe_connection => FALSE );
 
     IF p_status != 'SUCCESS' THEN
        RAISE v_exception;
     END IF;
 
	 IF p_type_move = 'PUT' THEN
 
	     dummy := ftp_interface.put (
                    p_localpath            => p_localpath,
                    p_filename             => p_filename,
                    p_remotepath           => p_remotepath,
                    p_username             => p_username,
                    p_password             => p_password,
                    p_hostname             => p_hostname,
                    v_status               => p_status,
                    v_error_message        => p_error,
                    n_bytes_transmitted    => p_bytes_trans,
                    d_trans_start          => p_trans_start,
                    d_trans_end            => p_trans_end,
                    p_port                 => 21,
                    p_filetype             => 'ASCII',
                    p_mainframe_ftp        => FALSE,
                    p_mainframe_cmd        => '' );
 
         IF p_status != 'SUCCESS' THEN
            RAISE v_exception;
         END IF;
 
     ELSIF p_type_move = 'GET' THEN
 
		 dummy := ftp_interface.get (
                    p_localpath            => p_localpath,
                    p_filename             => p_filename,
                    p_remotepath           => p_remotepath,
                    p_username             => p_username,
                    p_password             => p_password,
                    p_hostname             => p_hostname,
                    v_status               => p_status,
                    v_error_message        => p_error,
                    n_bytes_transmitted    => p_bytes_trans,
                    d_trans_start          => p_trans_start,
                    d_trans_end            => p_trans_end,
                    p_port                 => 21,
                    p_filetype             => 'ASCII',
                    p_mainframe_ftp        => FALSE,
                    p_mainframe_cmd        => '' );
 
         IF p_status != 'SUCCESS' THEN
            RAISE v_exception;
         END IF;
 
     END IF;
 
     p_error := 'OK';
 
  EXCEPTION 
     WHEN v_exception THEN
         NULL;
     WHEN OTHERS THEN
         p_error := 'ERROR: ' || SQLERRM;
  END move_file;

La llamada al procedimiento se realiza de manera muy fácil:

1
2
3
4
5
6
7
8
move_file('GET',
          '/datos',
          '/home',
          'test.txt',
          'usuario',
          'password',
          'ip_del_host',
          v_error);
* 49 Comentarios Email Imprimir

Pagina 8 de 24« Primera...78910...20...Ultima »