none
Carga Masiva Datos Oracle a Sql Server 2008 R2 RRS feed

  • Pregunta

  • Buenas Tardes Compañeros, la verdad quisiera que me ayuadaran con la siguiente situacion:

    Necesito realizar cargas masivas de tablas, las tablas se encuentran en Oracle y las deseo trasladar a SQL Server 2008 R2. He pensado en dos soluciones pero no se cual es la mas optima, no es necesario crear las relaciones que se tengan de la BD de Oracle.

    1. La primera opcion que pense es crear una programa en C# que consulte las tablas que necesito y crear archivos formateados y luego cargarlos con un procedimieto almecenado con la instruccion Bulk Insert, pero creo que seria un poco lento ya que cada tabla tiene alrededor de 300,000 registos, y crear archivos para cada tabla, y tener el control de archivos seria mas conmplejo y lento. Ademas es un proceso que debo correr a diario.

    2. La segunda opcion es crear un SSIS, que realice el procedimiento de copiado de las tablas, pero la verdad seria la primero vez que realizara uno, pero la coneccion a Oracle se puede realizar alli?? y luego puede copiar toda la tabla a SQL Server.

    Las restriciones que tengo, es que en oracle solo tengo un usuario de lectura, desarrollo en Visual Studio 2010, SQL Server 2008 R2.

    Me gustaria que me pudieran aportar ideas de como realizar este proceso que debe correr todos los dias en la madrugada de forma automatica.

    Saludos, tengo poco tiempo para realizar este proceso......

    jueves, 31 de mayo de 2012 20:06

Todas las respuestas

  • Te propongo tres soluciones:

    1) Con Visual Studio: Abre una conexión a Oracle y otra a SQL Server. A través de la conexión a Oracle traete los registros por bloques, por ejemplo de 1000 en 1000, a un DataTable en memoria. Y luego usa un objeto SqlBulkInsert para insertar de golpe todos esos registros desde el DataTable a SQL Server.

    2) Con SSIS: No hay ningún problema. Puedes definir una conexión a Oracle y otra a SQL Server y crear un DataFlow que mueva registros de un sitio al otro. Es la solución más simple si sabes cómo usar SSIS.

    3) Con Replicación Heterogénea de SQL Server. Puedes configurar replicación desde Oracle a SQL Server, y se hará de forma automática con la frecuencia que tú quieras, trayendo solamente los registros que hayan cambiado desde la última vez, con lo que será probablemente la opción más eficiente. El inconveniente es que para configrarla se necesitará momentáneamente un usuario con permisos elevados en Oracle.

    domingo, 3 de junio de 2012 7:50
  • Mucha gracias por las Ideas estimado, te comento que he estado probando con el SSIS pero he tenido problemas al momento de realizar la coneccion me dice que no tengo instalado Microsoft OLE DB Provider for oracle, pero ya tendo instalado el cliente de oracle que incluia los componentes, la instruccion tnsping y el server responde, pero bueno, no se si me podrias sugerir algo.

    Con respecto a tus respuestas me parace muy buena las consultas de 1000 en 1000, respecto a esto me gustaria, comentarte:

    Como tengo varias tablas en Oracle y necesito teminar los mas pronto este proceso, se me ocurre que son como 15 tablas las que debo copiar podria manejar tres subprocesos para que este consultando tres tablas y llenado las mismas en SQL Server, esto podria ser un servicio de Windows que se ejecute solo una vez al dia, esto seria posible???

    Para realizar la coneccion en .net para oracle necesito ODAC que es un componete de Oracle para .net???

    Bueno estimado te agradezco mucho a la espera de tus comentarios.

    Si me pudieras proporcionar informacion te lo agradeceria,....

    Estoy abierto a tus comentarios, gracias........

    martes, 5 de junio de 2012 15:33
  • A ver, varias cosillas:

    - El objeto de ado.net para transferencias masivas no se llama SqlBulkInsert sino SqlBulkCopy. Perdón por mi error.

    - Hay una sobrecarga que admite como parámetro un IDataReader (en lugar de un DataTable). Si le pasas un datareader abierto contra al tabla de Oracle, te evitas el preocuparte de leer los registros de 1000 en 1000. Ya se encarga el SqlBulkCopy de ir leyendo los registros que le hagan falta para irlos insertando en el Sql Server.

    - Para la conexión en .Net con Oracle tienes dos alternativas: Usar el proveedor de Microsoft, si estás programando con una versión del Framework anterior a la 4, o usar el proveedor de Oracle. Utilizan distintos espacios de nombres y tienen distintos requisitos de librerías, así que tendrás que escoger el que te convenga y configurarlo adecuadamente.

    - En cuanto a SSIS, el proveedor al que te refieres se descarga aqui:

    http://msdn.microsoft.com/en-us/library/windows/desktop/ms675851(v=vs.85).aspx

    pero se considera obsoleto y además no hay versión de 64 bits. Es preferible que conectes por medio de OleDb.

    martes, 5 de junio de 2012 16:08
  • Muchas Gracias por tus sugenencias estimado:

    Lo del IDataReader es equivalente a DataReader???,  entiendo que conforme va leyedo va realizando la insercion, la verdad no he utilizado este componente cuando te refieres a pasarlos abierto es que realizo la consulta por Ejemplo: "Select * from Clientes" en oracle voy leyendo el reader y lo voy insertando con SqlBulkCopy a SQL Server con un cliclo While por ejemplo???.

    Esto en Una tabla de 300,000 registros por el select  * ,no seria muy pesada para oracle, o no me debo de preocupar por ello??

    Con respecto a este proceso podria manejar los subproceso para hacer esto en varias tablas al mismo tiempo???

    No se si podrias proporcionarme un ejemplo o una referencia, gracias...

    Gracias, me has estado orientando bastante,

    A la espera de tus comentarios....

    martes, 5 de junio de 2012 17:08
  • Lo de IDataReader es una interfaz. Cuando un método toma una interfaz como parámetro, puedes pasarle un objeto de cualquier clase que implemente esa interfaz. En particular, todos los DataReaders (SqlDataReader, OleDbDataReader, OracleDataReader, ...) implementan IDataReader, y por lo tanto cualquiera de ellos se le puede pasar al método WriteToServer del SqlBulkCopy.

    Lo que tienes que hacer es preparar el DataReader contra Oracle con una sentencia como la que mencionas, pero después no tienes que ir leyendo ni tienes que usar un bucle While. Simplemente le entregas el DataReader al método WriteToServer y él se encarga de todo (por dentro, efectivamente tiene un While que va leyendo del reader, pero eso está dentro de la dll de .Net, y resulta invisible para tí).

    No te debes preocupar por el tema de los 300.000 registros. Cuando envías la select, lo que ocurre es que los 300.000 registros empiezan a viajar poco a poco, uno detrás del otro, por la línea que conecta el servidor Oracle con el programa que los está leyendo. Este programa, según los lee, los va inyectando por lotes en el Sql Server. Por lo tanto, en ningún momento llegas a tener en memoria los 300.000 registros en ninguna de las tres máquinas que intervienen (el servidor Oracle, el ordenador con el programa de .Net que mueve los registros, y el servidor SQL Server).

    ¿Vale la pena iniciar varios hilos que muevan los registros de las tres tablas simultaneamente? Lo dudo. Depende del hardware que tengas, pero seguramente el cuello de botella lo vas a tener en la grabación de los Logs en el lado del SQL Server (mientras el disco no confirma que ha grabado el "log" de la inserción no se da por concluida la grabación del registro). Esto limita el número de registros que puedes grabar por segundo, y da igual a qué tabla pertenezcan, y además incluso aunque las tres tablas estén en distintos ejes, el Log siempre es común a todas ellas. Podrías hacer unas cuantas pruebas para verificarlo, pero dudo que tardes menos en transferir las tres tablas en paralelo que en hacer secuencialmente una detrás de otra.

    martes, 5 de junio de 2012 20:41
  • Muchas Gracias por tu ayuda, y observaciones que me han sido de gran aporta a la solucion de la aplicación no me queda mas que comenzar.

    Gracias, te comentare como se desarrollo el proyecto

    Erwin Méndez.
    miércoles, 6 de junio de 2012 15:26