Para acceder a las tablas de una BD en formato SQL server, teniendo instalado un cliente nativo, por ejemplo de sql server 2012 o 2015, podemos usar 3 métodos:
1. la clase Cado de script de Ingrid 7 (no está documentada, sólo hay en la BD comun algún ejemplo que copia una BD de un motor a otro)
2. la librería javascript libADO de la BD comun. Podemos acceder a todas las tablas y campos de una forma más trabajosa (programando todo el script) que con una conexión fieado, pero permite leer tabla de relaciones o cruzar campos de tablas auxiliares que pueden dar problemas con fieado.
3. Establecer una conexión fieado. Basta con crear un archivo de texto de cadena de conexión ADO .cnx como:
Provider=SQLNCLI11; Server=.\SQLEXPRESS;Database=arbomap; Integrated Security=SSPI;
y arrastrar el archivo sobre un concepto de BD de clase fieado, como si de una BD se tratara.
Esta es la forma más sencilla de cargar campos en tablas de propiedades, conceptos y rótulos, y además permite analizar la BD (ver todas las tablas, las que tienen contenido, qué tipos de datos...
Para usar esta tercera forma, tenemos que tener instalado el motor de BD Sql server, el cliente, y la base en ese motor, adjuntada o dentro de él.
El primer problema es que una BD en formato .MDF, por ejemplo como las BD de Arbomap.net v3, que funcionan con MSDE2000 (que es la versión express o gratuita del sql server 2000), no son compatibles con sql server 2008 o 2012, como versión más reciente, se reconoce el formato de BD en sql server 2005.
Por tanto instalo el motor 2005, se adjunta la BD .MDF y con ello se puede usar la herramienta Importar y exportar datos (64 bits) de sql server 2012 para tomar como origen la BD 2005 y destino una BD nueva creada en 2012. Así ya la tenemos creada con formato v2012 y podemos trabajar con todas las herramientas de 2012.
El segundo problema es que con javascript no podemos acceder a los datos binarios de las tablas de la base (como fotos o archivos .SHP, .DGN... incrustados). Para conseguirlo, podemos ejecutar un script de transact-sql (T-sql), directamente desde el Sql server management studio 2012, que nos permite leer campos binarios y volcarlos en un archivo.
Para ello creamos un archivo .sql y lo abrimos en el depurador de Sql server management studio 2012.
A. El primer paso es activar la ejecución de shell o línea de comandos desde el entorno, con:
EXEC sp_configure 'show advanced options', 1;
GO
RECONFIGURE;
GO
EXEC sp_configure 'xp_cmdshell',1
GO
RECONFIGURE
GO
Si no ha habido problemas, podemos ejecutar el comando BCP desde el entorno.
B. El segundo paso, volcar un archivo de formato .FMT con la estructura de la tabla que queremos exportar, como:
Declare @sql1 varchar(200)
SET @sql1 = 'bcp
arbomap.dbo.Gb_ContenidoDeFicheroSHP format nul -T -n -f C:\tmp\formato.fmt
-S ' + @@SERVERNAME
select @sql1
EXEC master.dbo.xp_CmdShell
@sql1
Donde tras el modificador -f va el archivo de salida, que es de texto y tiene un formato como:
11.0
11
1 SQLINT
0 4 "" 1 NumeroIdentificativo ""
2
SQLCHAR 2 100 "" 2 NombreDeFichero
Modern_Spanish_CI_AS
3 SQLDATETIME 1 8 "" 3 FechaSHP
""
4 SQLINT 1 4
"" 4 LongitudDeFicheroSHP ""
5 SQLIMAGE
4 0 "" 5 DatosDeFicheroSHP ""
6 SQLDATETIME 1 8 "" 6 FechaSHX
""
7 SQLINT 1 4
"" 7 LongitudDeFicheroSHX ""
8 SQLIMAGE
4 0 "" 8 DatosDeFicheroSHX ""
9 SQLDATETIME 1 8 "" 9 FechaDBF
""
10 SQLINT 1 4 "" 10
LongitudDeFicheroDBF ""
11 SQLIMAGE 4 0
"" 11 DatosDeFicheroDBF ""
Es el volcado de la definición de campos, que necesitamos para usar BCP: el primer núm es la versión de SQLNCLI, el segundo el nº de líneas, la 6ª columna el orden de campos...
La referencia de este formato está en: https://msdn.microsoft.com/es-es/library/ms191479(v=sql.120).aspx
Ahora manipulamos el archivo para dejarlo:
11.0
1
1 SQLIMAGE 0 0 "" 1
DatosDeFicheroSHP ""
y lo guardo como formato1.fmt, con lo que sólo accederemos al campo que contiene el binario del SHP, por ejemplo.
C. Por último, para sacar los datos binarios de un sólo campo en un solo registro, basta con ejecutar:
OJO!, no se pueden partir las líneas de cada comando en varias con un retorno de carro:
DECLARE @sql1 varchar(500)
SET @sql1 = 'BCP
"SELECT DatosDeFicheroSHP FROM arbomap.dbo.Gb_ContenidoDeFicheroSHP
where NumeroIdentificativo=1530" QUERYOUT C:\ParlaArbomap\1530.shp
-T -f C:\ParlaArbomap\formato1.fmt -S ' + @@SERVERNAME
EXEC
master.dbo.xp_CmdShell @sql1
He seleccionado un registro por su clave primaria, y lo exporto a un archivo concreto. Tengo que saber que es un SHP o un JPG, o lo que sea, para ponerle la extensión, y le indico el formato de campo.
Pero si queremos hacerlo en un bucle recorriendo todos los registros de una tabla, una de las formas de hacerlo es definiendo un cursor. Este sería el script a ejecutar:
DECLARE @MyCursor CURSOR;
DECLARE @MyField
VARCHAR(200);
BEGIN
SET @MyCursor
= CURSOR FOR
SELECT NumeroIdentificativo from
arbomap.dbo.Gb_ContenidoDeFicheroSHP order by NumeroIdentificativo
OPEN @MyCursor
FETCH NEXT FROM @MyCursor
INTO @MyField
Declare @sql1 varchar(200)
WHILE @@FETCH_STATUS = 0
BEGIN
SET @camino= 'C:\ParlaArbomap\SHP\'
+ @MyField + '.shp';
SET @sql1 = 'BCP "SELECT DatosDeFicheroSHP FROM arbomap.dbo.Gb_ContenidoDeFicheroSHP where
NombreDeFichero=' + @MyField + '" QUERYOUT ' + @camino + ' -T -f C:\ParlaArbomap\formato1.fmt
-S ' + @@SERVERNAME
--PRINT @sql1
EXEC
master.dbo.xp_CmdShell @sql1
FETCH NEXT FROM @MyCursor
INTO @MyField
END;
CLOSE @MyCursor ;
DEALLOCATE @MyCursor;
END;
En caso de exportar archivos SHP, necesitaremos realizar la misma operación con el campo DatosDeFicheroDBF de esa misma tabla (los datos SHX de índices no son necesarios).
La exportación de la BD de parques y jardines de Parla, aunque ha funcionado bien con 2.200 archivos jpg y con 150 archivos SHP, ha fallado con otros, sólo cabe suponer que porque los datos ya estaban corruptos en el campo binario de la BD. Al exportar, se encuentran archivos truncados que no pueden abrir ni DXI, ni el visor tatukGIS.
Una herramienta en la distribución de Ingrid 7, nos permite reparar la estructura de SHP y DBF de archivos dañados (directorio de la distribución: \util\SHPrepair\shapechk.exe)
Otro método para recorrer los registros, en vez de con un cursor y con BCP, se puede hacer también con CLR (procedimientos a los que se puede llamar desde C#): http://stackoverflow.com/questions/10325338/fastest-way-to-export-blobs-from-table-into-individual-files
Y un artículo que complementa los pasos explicados aquí (ejemplo de exportación de BLOBs): http://www.codeproject.com/Tips/372613/SQL-Server-BLOB-Import-and-Export