Buenas a todos,
Estoy buscando información sobre cómo realizar el volcado de datos de un fichero a una tabla de la base de datos (sql server 2005) con la peculiaridad de que la tabla no tiene el mismo formato que el fichero (tiene menos columnas y en distintos orden) . No sé por dónde empezar porque no he encontrado ningún ejemplo o guía del que aprender a realizarlo.
Un saludo y muchas gracias de antemano.
Comentarios
Hola Rikku como estas !, bueno te paso a contestar tu inquietud:
Bueno la carga y transformación de datos de dos tablas distintas ya sea con menor cantidad de columnas u orden de columnas distintos, tenes dos maneras de realizarlo por TSQL y objetos dentro de IS de SQL Server, te las paso a detallar:
IS (Integration Services): Por esta vía tenes que crear un nuevo paquete de IS (DTS) y configurar origen y destino de los datos(OleDb Datasource y OleDbDestination) previamente configurando un Data Source en el proyecto y luego realizar una transformación o copia de los datos que te interesan entre tablas. El archivo que te genera tranquilamente lo podes agendar por SQL Server para que sea ejecutado cuando lo necesites. También podes utilizar el objeto Bulk Insert task.
TSQL: Podes realizarlo primero generando un archivo de formato con la utilidad BCP y luego invocas ese archivo con el Bulk Insert mediante la sentencia de ejemplo que te anexo:
BULK INSERT BaseAfectada..Mytabla
FROM 'C:\MyTabla-c.dat' WITH (FORMATFILE='C:\MyTablaformat-c-xml.xml');
GO
Command-prompt: Directamente con la utilidad BCP extrayendo los datos con un query en el bcp y extrayéndolo a un archivo y cargándolos con la misma utilidad a la tabla destino utilizando el archivo generado.
Ej:
bcp "SELECT FirstName, LastName FROM AdventureWorks.Person.Contact ORDER BY LastName, Firstname" queryout Contacts.txt -c -T
bcp AdventureWorks.Person.Contact2 in Contacts.txt -T -c
Espero te sirva, un abrazo virtual !.
¡Muy buenas, JuanPL!
Muchísimas gracias por la respuesta, me has dado mucha información.
Ya había pensado en usar DTS o SSIS pero le problema es que los servicios de integración, según me han dicho, requiren un tipo de licencia concreta con la que no cuento. De modo que voy a probar con la segunda opción que me diste porque suena muy bien.
Mil gracias por la ayuda! :)
Hola !, la licencia para SQL Server Integration services es un producto que viene incluido con la licencia de Microsoft SQL Server, es decir con el Motor de Base de datos, por lo cual, no necesitas una licencia especial o aparte.
Abrazo virtual!
Tambien depende con que version de SQL estes trabajando: Te paso un link con respecto a 2005/2008 donde podras chequear las caracteristicas habilitadas.
http://www.microsoft.com/Sqlserver/2005/en/us/compare-features.aspx
http://www.microsoft.com/downloads/details.aspx?FamilyId=4C6BA9FD-319A-4...
http://www.microsoft.com/sqlserver/2008/en/us/express.aspx
Abrazo Virtual.
Buenas de nuevo:
Hice pruebas creando el format file a partir del siguiente comando:
C:\>bcp BBDD.dbo.Mediciones format nul -S PCX\SQLEXPRESS -T -n
-f GPS.fmt
para una tabla con los siguiente campos:
-Fecha (varchar(50)) -> le puse varchar para realizar la prueba para evitar problemas, luego ya probaré con datetime.
-Latitud (decimal(18,8)).
- TipoLatitud (varchar(50)).
-Longitud (decimal(18,8)).
- TipoLongitud (varchar(50)).
Lo que ha generado lo siguiente:
9.0
5
1 SQLCHAR 2 50 "" 1 Fecha Modern_Spanish_CI_AS
2 SQLDECIMAL 1 19 "" 2 Latitud ""
3 SQLCHAR 2 50 "" 3 TipoLatitud Modern_Spanish_CI_AS
4 SQLDECIMAL 1 19 "" 4 Longitud ""
5 SQLCHAR 2 50 "" 5 tipoLongitud Modern_Spanish_CI_AS
hasta ahí todo normal.
Cuando trato de ejecutar el procedimiento almacenado, si especifico el format file:
BULK INSERT BBDD.dbo.Mediciones
FROM 'C:\Prueba.txt'
WITH
(
FIELDTERMINATOR = ',',
ROWTERMINATOR = ';',
FORMATFILE = 'C:\GPS.fmt'
);
Me da los siguientes errores:
Mens 4866, Nivel 16, Estado 7, Procedimiento sp_medicionesposiciones_insert, Línea 10
Error de carga masiva. Columna demasiado larga en el archivo de datos para la fila 1, columna 1. Compruebe que especificó correctamente los valores para el terminador de campo y el terminador de fila.
Mens 7399, Nivel 16, Estado 1, Procedimiento sp_medicionesposiciones_insert, Línea 10
El proveedor OLE DB "BULK" para el servidor vinculado "(null)" informó de un error. El proveedor no proporcionó información acerca del error.
Mens 7330, Nivel 16, Estado 2, Procedimiento sp_medicionesposiciones_insert, Línea 10
No se puede recuperar una fila del proveedor OLE DB "BULK" para el servidor vinculado "(null)".
En cambio si lo ejecuto sin el FORMATFILE lo hace correctamente.
El contenido del fichero desde el que quiero realizar la carga:
23/02/2010,4330.4735414,N,00352.9613565,W; (Esta es la primera línea y el resto son del mismo estilo)
Luego por otro lado, si en vez de tener ese contenido tendría este otro:
23/02/2010,CAMPOSOBRANTE,4330.4735414,N,00352.9613565,W;
¿Cómo podría indicarle que no utilice el campo 2? ¿modificando la primera columna del archivo GPS.fmt como:
9.0
Num columnas (no sé si sería 5 ó 6)
1 <- ¿posición de la columna en el archivo GPS.fmt?
3
4
5
6
?
Un saludo y muchas gracias de antemano
Bueno, voy comentado los avances sobre este tema.
En el archivo de formato me faltaba indicar cuales eran los separadores de campo y fila, lo estaba haciendo en el procedimiento almacenado por lo que cambié ambos. Me daba varios errores nuevos, pero poniendo el prefix length (3º columna) a 0, tal y como me aconsejo uno de esos sabios de internet, y me quité esos errores pero me dió un nuevo error con el que estoy lidiando ahora, que es el siguiente:
Mens. 9803, Nivel 16, Estado 1, Línea 1
Datos no válidos para el tipo "numeric".
Mi BULK INSERT está de la siguiente manera:
BULK INSERT BBDD.dbo.Mediciones
FROM 'C:\Prueba.txt'
WITH ( FORMATFILE = 'C:\GPS.fmt' );
Y MI FORMATFILE tiene el siguiente contenido:
9.0
5
1 SQLCHAR 0 50 "," 1 Fecha Modern_Spanish_CI_AS
2 SQLDECIMAL 0 19 "," 2 Latitud ""
3 SQLCHAR 0 50 "," 3 TipoLatitud Modern_Spanish_CI_AS
4 SQLDECIMAL 0 19 "," 4 Longitud ""
5 SQLCHAR 0 50 "\r\n" 5 tipoLongitud Modern_Spanish_CI_AS
El archivo desde el que estoy volcando los datos tiene lo siguiente:
1000, 20000.0, 30000, 40000.0, 50000
2000, 30000.0, 22222, 33333.0, 44444
por lo que no veo nada raro ahí tampoco. Si ejecuto el BULK INSERT sin el FORMATFILE me lo hace perfectamente, así que tengo algún error en el archivo de formato que no acabo de dar con él.
Quizás visto desde fuera sea más sencillo. Ya os contaré a ver si logro encontrar la solución.
Un saludo!