Ver Mensaje Individual
  #2 (permalink)  
Antiguo 17/12/2007, 12:47
Avatar de matanga
matanga
 
Fecha de Ingreso: octubre-2007
Ubicación: España
Mensajes: 1.091
Antigüedad: 17 años
Puntos: 85
Re: actualizar una tabla a partir de otra tabla remota

Hola,

Primero que nada, voy a suponer que la base de datos remota es Oracle.

Hago un TNSPING desde el servidor de Oracle para asegurarme que puedo resolver el nombre de la base de datos remota.

Código:
oracle@buo:~> tnsping RORA10

TNS Ping Utility for Linux: Version 10.2.0.1.0 - Production on 20-DEC-2007 17:48:50

Copyright (c) 1997, 2005, Oracle.  All rights reserved.

Used parameter files:
/u01/app/oracle/product/10.2/db_1/network/admin/sqlnet.ora


Used TNSNAMES adapter to resolve the alias
Attempting to contact (DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = buo)(PORT = 1521)) (CONNECT_DATA = (SERVER = DEDICATED) (SERVICE_NAME = ORA10)))
En la base de datos local, donde quiero cargar los datos, creo un dblink a la base de datos remota y hago un pequeño test para ver que todo funcione bien.

Código:
SQL> create database link rora10g                                               
  2  connect to remote_user
  3  identified by password
  4  using 'RORA10';

Database link created.

SQL> select * from dual@rora10g;

D
-
X
Para el ejemplo, tengo dos tablas, T1 en local y T1@RORA10G en remoto, la idea es pasar los datos de la remota a la local.

Código:
SQL> desc t1;
 Name                                      Null?    Type
 ----------------------------------------- -------- ----------------------------
 ID                                                 NUMBER
 NOMBRE                                             VARCHAR2(30)

SQL> desc t1@rora10g;
 Name                                      Null?    Type
 ----------------------------------------- -------- ----------------------------
 ID                                                 NUMBER
 NOMBRE                                             VARCHAR2(30)

SQL> select * from t1@rora10g;

        ID NOMBRE
---------- ------------------------------
         1 nombre 1
         2 nombre 2

SQL> select * from t1;

no rows selected
Ejecuto un MERGE para que actualice los datos existentes o inserte los nuevos, ademas validamos que todo funcione bien.

Código:
SQL> MERGE INTO t1 D
  2     USING (SELECT id, nombre FROM t1@rora10g) S
  3     ON (D.id = S.id)
  4     WHEN MATCHED THEN UPDATE SET D.nombre = S.nombre
  5     WHEN NOT MATCHED THEN INSERT (D.id, D.nombre)
  6       VALUES (S.id, S.nombre)
  7  /

2 rows merged.

SQL> select * from t1;

        ID NOMBRE
---------- ------------------------------
         1 nombre 1
         2 nombre 2
Listo, ya tengo lo datos en T1 local, lo ultimo que falta es hacer una tarea programada en Oracle para que ejecute esto una vez por dia, para esto utilizo el paquete DBMS_SCHEDULER.

Código:
SQL> r
  1  BEGIN
  2  DBMS_SCHEDULER.CREATE_JOB(
  3     job_name          =>  'merge_t1',
  4     job_type          =>  'PLSQL_BLOCK',
  5     job_action        =>  'MERGE INTO t1 D
  6                            USING (SELECT id, nombre FROM t1@rora10g) S
  7                            ON (D.id = S.id)
  8                            WHEN MATCHED THEN UPDATE SET D.nombre = S.nombre
  9                            WHEN NOT MATCHED THEN INSERT (D.id, D.nombre)
 10                            VALUES (S.id, S.nombre)
 11                            ',
 12     start_date        =>  SYSDATE,
 13     repeat_interval   =>  'FREQ = DAILY; INTERVAL = 1');
 14* END;
SQL> /

PL/SQL procedure successfully completed.
Consideraciones varias,

1. El MERGE es una buena forma de actualizar los datos de una tabla a otra, pero tambien puedes utilizar INSERT, UPDATE y DELETE, intenta evitar el uso de cursores.

2. Dentro del DBMS_SCHEDULER puse directamente la sentencia SQL, talvez sea mas conveniente programar la llamada a un procedimiento que realice la actualizacion de datos, esto lo digo porque, llegado el caso que necesites modificar la logica del codigo, sera mas facil modificar un procedimiento que una tarea programada en Oracle.

3. Te dejo un link al DBMS_SCHEDULER para que sepas como modificar los intervalos de tiempo en que se ejecutan las tareas programadas.
http://download.oracle.com/docs/cd/B...htm#sthref6598

4. Si la bases de datos remota no es Oracle, pero soporta ODBC, puedes utilizar un dblink a traves de heterogeneous services.

5. Si se te complica con el punto 4, puedes bajar los datos a un fichero de texto y cargarlos en forma temporal a Oracle utilizando SQL*Loader o Tablas Externas.

Saludos

Última edición por matanga; 17/12/2007 a las 12:58