PowerBI: Anunciado por fin acceso desde PowerBI a SSAS multidimensional

Posted by Miguel Egea | Posted in Analisys Services, PowerBI | Posted on 23-11-2015

0

En el update de noviembre del PowerBI desktop ya tenemos por fin el acceso a SSAS Multidimensional. Aún así se considera una funcionalidad Beta por lo que hay que habilitarlo específicamente.

Si como yo estás deseando probar la funcionalidad, no te olvides de leer este artículo

A disfrutar!

MDX: Periodos paralelos y crecimiento

Posted by Miguel Egea | Posted in Analisys Services, MDX | Posted on 19-11-2015

0

A veces el código MDX resulta difícil de escribir, en sí no es un lenguaje complicado, pero muchas veces cuesta distinguir cuando una función espera una tupla, un miembro o un conjunto, y además, como es algo que no se utiliza todos los días, sino cuando estamos poniendo la guinda a nuestro cubo terminado, la memoria nos juega malas pasadas.

Si juntamos memoria y sintaxis, el resultado es que crear una métrica se puede convertir en una tarea complicada.

Truco

Es verdad que podemos crear la métrica en la sección calculo del cubo, pero generalmente resulta mas sencillo crear primero la métrica en management studio, porque luego llevarla es super sencillo y el proceso de depuración se hace mucho menos pesado. Además Management Studio, cuando cometemos un error, si nos ponemos encima del error con el cursor, nos da una explicación algo mejor que excel para el mismo error.

Crea una plantilla del estilo

With member Measures.Test as 1

select Measures.test on 0,

Dimensiones  on 1

from tu cubo

una vez escrita esa plantilla, sustituye tu 1 por la fórmula que quieras escribir y ve depurando hasta que te funcione.

Mismo valor el año anterior

Para calcular el mismo valor del año anterior hemos usado la plantilla que decíamos, escribiendo primero esto

 

with member Measures.Anterior as
   1
select {Measures.[Internet Sales Amount],measures.Anterior} on 0 ,
[Date].[Calendar].[Calendar Year] on 1
from [Adventure Works];

Después vamos a sustituir el 1 por la función parallelperiod, la función parallelperiod recibe tres parámetros, Nivel, posiciones,miembro,

Nivel: Si queremos ir años, meses o días hacia atrás

Posición: El numero de meses, días o años que queremos retroceder (en valor positivo) por ejemplo 3, a nivel de año, tres años hacia atrás

Miembro: Por defecto será el currentmember de la dimension tiempo, por lo que la mayoría de las veces no es necesario poner este parámetro

Parallelperiod  devuelve un miembro, así que lo que debemos esperar no es una medida,

parallelperiod ([Date].[Calendar].[Calendar Year],1)  devolverá el mismo periodo del año anterior, si estamos a nivel de mes, el mismo mes del año anterior, si estamos a nivel de dia el mismo dia del año anterior.

A partir de ese miembro si podemos construir una tupla  que nos devuelva el valor de las ventas en ese momento, eso se hace encerrando entre paréntesis el miembro que acabamos de calcular y una métrica

(parallelperiod ([Date].[Calendar].[Calendar Year],1),Measures.[Internet Sales Amount])

Con esta función si tenemos el mismo valor del año anterior. Ahora podemos empezar a probar basados en nuestra plantilla es decir sustituyendo el 1 por esta formula

with member Measures.Anterior as

(parallelperiod ([Date].[Calendar].[Calendar Year],1),Measures.[Internet Sales Amount])

select {Measures.[Internet Sales Amount],measures.Anterior} on 0 ,

[Date].[Calendar].[Calendar Year] on 1

from [Adventure Works];

Esto si nos da el resultado.

Ahora vamos a calcular el crecimiento. Esto nos lleva a otra plantilla, Crecimiento es (Actual-Anterior)/Anterior, como anterior está escrito 2 veces y es la misma formulita esta de arriba, resulta mas sencillo crear una medida (aunque la dejemos oculta) que tenga el valor anterior y simplemente usarla

así pues haremos una plantilla de este tipo

with

member Measures.Anterior as

1

member Measures.Crecimiento as

1+Measures.Anterior

select {Measures.[Internet Sales Amount],measures.Anterior,Measures.Crecimiento} on 0 ,

[Date].[Calendar].[Calendar Year] on 1

from [Adventure Works];

De forma que en el crecimiento estamos usando el anterior.

la formula completa, puesto que es muy simple ahora restar y dividir (sin olvidar los paréntesis) quedaría  así

with

member Measures.Anterior as

(parallelperiod ([Date].[Calendar].[Calendar Year],1),Measures.[Internet Sales Amount])

member Measures.Crecimiento as

iif(Measures.Anterior=0,0,

(Measures.[Internet Sales Amount]-Measures.Anterior)/Measures.Anterior),format_string=“percent”

select {Measures.[Internet Sales Amount],measures.Anterior,Measures.Crecimiento} on 0 ,

[Date].[Calendar].[Calendar Year] on 1

from [Adventure Works];

 

 

¿están mis paquetes ejecutándose en tiempo?

Posted by Miguel Egea | Posted in Relacional, SQL Server Integration Services | Posted on 02-11-2015

0

El rendimiento es un tema recurrente en los que nos dedicamos a este mundo de las bases de datos, es muy común que necesitemos saber, -y aún más importante demostrar -, que nuestros paquetes se están ejecutando en tiempo y forma.
Para responder a esta pregunta vamos a usar dos conocimientos distintos, de una parte el conocimiento de las vistas y catalogs del sistema, de otra parte el conocimiento estadístico.

Catálogos del sistema

En nuestro caso estamos circunscritos al ambiente integration services usando el SSIS Catalog, pero no costaría mucho hacer este mismo ejercicio para jobs, para paquetes que no estén en el catalogo, para logs propios o para cualquier otro registro de tareas que hacemos.

En el caso de este artículo, insisto que estamos en el ambiente del SSIS catalog así que los queries que vamos a ver están relacionados solo con este mundo.

Lo primero vamos a examinar la tabla catalog.executions.

La tabla nos ofrece un montón de información, de hecho nos agrupa el id de ejecución para determinar si hay paquetes hijos ejecutados en el mismo proceso, también nos da el estado, el enviroment contra el que se ejecutó, el sid y el nombre del ejecutador, si se hace o no en 32 bits, en resumen un montón de información que nos puede ser útil en otros casos pero que no es relevante para nuestro estudio.

Cuando miramos la fisonomía de un proyecto de integración, solemos tener un paquete maestro, un paquete orquestador que es el que se encarga de eso, de orquestar y ejecutar todos los demás paquetes, ese paquete orquestador, nos evita tener que hacer cientos de jobs, simplemente hacemos uno que desencadena todo el proceso en el orden que nos interesa. Lo normal es que ejecutemos primero la carga de datos desde origen a un area de staging o de data integration y de ahí pasemos nuestros datos al datawarehouse o al datamart correspondiente. Un solo paquete, o dos, dependiendo harían esa tarea. Si además hemos construido un paquete que procese un cubo de SSAS o que remate cualquier tipo de tareas entonces tendremos 2 o 3 paquetes que son los que hacen que nuestra información esté centralizada, controlada y monitorizada.

Bajo esta premisa, no tenemos que monitorizar todos los paquetes, al menos no de forma habitual, solo si el tiempo total ha variado sustancialmente podemos entrar a indagar cual, o cuales han sido las causas.

En resumen, para un paquete y un proyecto vamos a ver el tiempo que ha tardado, si ha terminado correctamente o no y el tiempo que ha tardado.

Como ejemplo podríamos poner este query

declare @pack nvarchar(100);

set @pack=‘Procesado Del Cubo.dtsx’

declare @project nvarchar(100);

set @project=‘MiProyecto’

select top (1) package_name, case when status=7 then ‘Ok’

when status=2 then ‘Running’

else ‘Fail’ end

Estado,

datediff(mi,start_time,end_time) minutos

From catalog.executions ce

where package_name = @pack

and project_name = @project

order by start_time desc

Si nos fijamos lo que hemos hecho es fijar el proyecto a “Mi proyecto”, el paquete se llamará “procesado del cubo” y ese query nos devuelve lo siguiente.

Si el estado es 7,2 o cualquier otro eso nos determina si se ha ejecutado ok, si está ejecutándose o si ha fallado.

La función datediff en minutos nos dice los minutos que ha tardado en ejecutarse el paquete y al quedarnos con el top1 order by star_time desc, estamos fijándonos exclusivamente en la ultima ejecución.

Estadística (desviación típica)

La Wikipedia define la desviación típica como “La desviación típica es una medida del grado de dispersión de los datos con respecto al valor promedio. Dicho de otra manera, la desviación estándar es simplemente el “promedio” o variación esperada con respecto a la media aritmética.”

Dicho en palabras más claras, nos dice cuanto suele una variable con respecto a su media.  Usando esta función estadística, podemos conseguir saber como de normal es un tiempo de ejecución.

Podríamos considerar normal todo lo que está en la media + – desviación típica, (es un criterio exigente)

En una distribución normal (los tiempos no van a ser una distribución normal porque la moda la media y la mediana no van a valer lo mismo), digamos que estaríamos entorno al 70% de los valores de una muestra. (se puede calcular con exactitud, pero no pretendo ser exacto sino dar una idea de lo que quiero decir).

Podéis mirar este gráfico para entender lo que quiero decir

https://commons.wikimedia.org/wiki/File:Standard_deviation_diagram_micro.svg

 

Aplicando el concepto

Tendríamos que comparar  el tiempo actual

case when datediff(SECOND,start_time,end_time)

con la media de los tiempos de ejecución del mismo paquete.

(select avg(datediff(ss,start_time,end_time)) from catalog.executions ce2 where ce2.package_name=ce.package_name and ce2.project_name=ce.project_name and ce2.[status]=7)

más 1 o 2 veces la desviación estándar dependiendo de lo permisivos o exigentes que queramos ser con las variaciones.

(select stdev(datediff(ss,start_time,end_time)) from catalog.executions ce2 where ce2.package_name=ce.package_name and ce2.project_name=ce.project_name and ce2.[status]=7)

El query completo quedaría algo así

declare @pack nvarchar(100);

set @pack=‘Procesado Del Cubo.dtsx’

declare @project nvarchar(100);

set @project=‘MiProyecto’

select top (1) package_name, case when status=7 then ‘Ok’

when status=2 then ‘Running’

else ‘Fail’ end

Estado,

datediff(mi,start_time,end_time) minutos,

case when datediff(SECOND,start_time,end_time)>

(select avg(datediff(ss,start_time,end_time)) from catalog.executions ce2 where ce2.package_name=ce.package_name and ce2.project_name=ce.project_name and ce2.[status]=7) +

(select stdev(datediff(ss,start_time,end_time)) from catalog.executions ce2 where ce2.package_name=ce.package_name and ce2.project_name=ce.project_name and ce2.[status]=7)

then ‘Warning tiempo’ else ‘Ok tiempo’ end TiempoEjecucion,

case when DATEDIFF(day,start_time,getdate())<1 then ‘Ok’

when DATEDIFF(day,start_time,getdate()) between 1 and 2 then ‘Warning’

else ‘Error’ end

UltimaEjecucion

From catalog.executions ce

where package_name = @pack

and project_name = @project

order by start_time desc

y si lo quieres copiar puedes hacerlo desde aquí

 

declare @pack nvarchar(100);
set @pack='Procesado Del Cubo.dtsx' 
 
declare @project nvarchar(100);
set @project='MiProyecto' 
 
select top (1) package_name, case when status=7 then 'Ok'  
					  	  when status=2 then 'Running'
						  else 'Fail' end
Estado,
					datediff(mi,start_time,end_time) minutos,
					case when datediff(SECOND,start_time,end_time)&gt; 
						(select avg(datediff(ss,start_time,end_time)) from catalog.executions ce2 where ce2.package_name=ce.package_name and ce2.project_name=ce.project_name and ce2.[status]=7) +
						(select stdev(datediff(ss,start_time,end_time)) from catalog.executions ce2 where ce2.package_name=ce.package_name and ce2.project_name=ce.project_name and ce2.[status]=7) 
					then 'Warning tiempo' else 'Ok tiempo' end TiempoEjecucion,
					case when DATEDIFF(day,start_time,getdate())

Lo que hemos añadido a lo ya explicado es simplemente una comparación de que no ha pasado mas de un dia desde la ultima vez que se ejecutó el paquete.

 

En resumen, bien con una sonda de los programas de monitorización, bien con un informe, o bien ejecutando este query cada dia podemos saber si el tiempo invertido en la ejecución de un proyecto ha sido normal o rara, y en función de eso, investigar en que puede haber cambiado para mejorar nuestros sistemas.

Quiero dejar claro que esto es una primera aproximación a la monitorización de servicios, que puede mejorarse mucho y que hay técnicas muy complejas de generación de baselines que no están en el alcance de este artículo, pero me pareció interesante compartirlo

 

Instalación de service pack o CU en SQL Server Cluster

Posted by Carlos Ignacio Agüero | Posted in Relacional, Trucos | Posted on 29-10-2015

0

• Hacer un backup de todas las bases de sistema (Master, model, MSDB)
• Si el cluster es activo / activo entonces mover todas las instancias a un solo nodo dejando así un nodo pasivo y uno activo con todas las instancias.
• Hacer un checkdb de las bases de sistema, si esto es correcto continuar con el procedimiento.
• Lo ideal sería hacer un checkdb de las bases de usuario.
• Copiar al nodo pasivo el service pack o CU.
• Ejecutar en el nodo pasivo en parche como administrador (run as administrator).
• Luego de instalar el parche en las instancias necesarias, hacer un reinicio del nodo pasivo.
• Verificar en el nodo pasivo que el parche haya quedado instalado de forma correcta
Entre al nodo pasivo
Vaya a la ruta : C:\Program Files\Microsoft SQL Server\120\Setup Bootstrap\Log
Habrá el archivo summary.txt , si el parche fue instalado ok el código de exit debe ser 0
• Hacer un failover por instancia del nodo activo
Hacerlo de a uno y probar conectividad a la instancia (esto puede demorar ya que en este punto hace la   actualización de las bases de sistema)
Verificar los log de SQL Server que todo este ok
• Aplicar el parche en el nodo activo
• Reiniciar el nodo activo.
• Verificar la correcta instalación en el nodo activo
Entre al nodo pasivo
Vaya a la ruta : C:\Program Files\Microsoft SQL Server\120\Setup Bootstrap\Log
Habrá el archivo summary.txt , si el parche fue instalado ok el código de exit debe ser 0

• Si esta todo ok, mover las instancias a cada nodo que corresponda.

Se recomienda hacer este tipo de operaciones en horario no crítico.

Importando Ficheros Excel con integration services

Posted by Miguel Egea | Posted in SQL Server Integration Services | Posted on 28-10-2015

0

La parte que puede llamar la atención de este artículo es que realmente SSIS ya trae un conector, de forma directa puedes leer ficheros de excel. La mala noticia es que ese conector no lee archivos de excel de extensiones xlsx. La razón es que no lee archivos de excel de versiones posteriores a la 2007.

excelconectorUna vez que ves esto… parece que el mundo se va a acabar, porque no puedes andar pidiendo que te cambien el formato de un archivo, de lo que se trata es leer lo que nos manden, y dejar los problemas técnicos del lado de los técnicos.

Siguiente Alternativa , usar el driver que del Offices Access Database Engine. ¡Bien! hay alternativa, ahora nos encontramos con otro problema… bastante tonto por cierto y es…

¿Qué versión de Office tienes instalada?. Si no tienes ninguna quizá no haya problema, no lo se, yo tengo la 2013 en este momento, y además la tengo en 64 bits.

Visual Studio trabaja en 32 bits en momentos de desarrollo así pues necesitamos tener ambos drivers instalados para poder desarrollar y poder probar agendando paquetes. Los que desarrollamos se ejecutaran  en 32 bits, los agendados en 64 bits.

Ojo, que si vas a las configuraciones del proyecto encontraras que parece que 64bitsse ejecuta en 64 bits. Yo no se que pasa por detrás, ni pretendo saberlo a estas alturas de la película, sin embargo lo que si se es que si instalo ambos drivers, esto debería funcionar, y que el paquete cuando se ejecute use el que le venga bien. :)

La teoría parece sencilla, así pues vamos a descargar los drivers en cuestión de la web de Microsoft . para mi versión de excel, y en este momento la url de descarga es http://www.microsoft.com/es-es/download/details.aspx?id=39358

Descargamos ambas versiones, y ahora nos disponemos a ejecutar primero una, por ejemplo la de 32 bits.

El resultado..

32bits error

El problema viene porque si tenemos la versión de 64 bits de office no nos deja instalar el acceso a datos de 32 bits. Supongo que tendrá su explicación, pero lo cierto es que para desarrollar con SSIS nos viene mal.  Instalando la versión de 64 bits no hay problema. Así que la instalé.

Investigando un poquito mas me descargué la versión de 32 bits pero para office 2010. La sorpresa grata fué que si ¡se instala!.

Si tu máquina de desarrollo es de 64 bits, y tu office instalado de 64 bits los pasos de instalación son :

  1. Instala la versión de 64 bits del Access RunTime de tu versión de office
  2. Instala la versión de 32 bits del Access RunTime de una versión distinta (¿Anterior?) de office
  3. Prueba que todo te funciona

Esta imagen muestra en mi caso el ordenorden de instalacion de instalación. El orden es importante.

Una vez que tenemos instalados los drivers de 32 y 64 bits, y que por tanto podemos usar ambas versiones de forma transparente estamos en disposición de crear una conexión a nuestro fichero excel.

Para hacerlo abrimos Integration Services y vamos a crear una conexión OLEDB.

En proveedor elegimos “Microsoft Office 12.0 Access Database Engine OLE DB Provider”. Este es justo el driver que acabamos de añadir con estas instalaciones.

Después la tarea se antoja más fácil, aunque como bien sabemos eso nunca es del todo así :).

Nos pide el driver que le digamos el nombre de un fichero, yo particularmente la primera vez pensé que bastaría con eso, pero al probar el botón mágico “test Connection”, obtenemos la siguiente imagen.

test connection

En fin. Hasta el final tenemos que tener un poquito de paciencia :-) la solución a este ultimo problema pasa por ir a la pestaña all del propio connection manager, la que veis en el dibujito debajo de “connection” y ahí en Extended Properties escribir las palabras mágicas “Excel 12.0”. con eso el resultado es el que veis como final de este artículo. conexionfinalizada

Ya estamos en disposición de usar Excel de forma mucho mas sencilla en nuestros desarrollos.

Hasta el próximo artículo!
 

 

Conociendo el Transaction Log

Posted by Carlos Ignacio Agüero | Posted in Relacional | Posted on 27-10-2015

0

1.1. Como SQL Server usa el Transaction Log
En SQL Server, el Transaction Log es un archivo físico, identificado por su extensión LDF. SQL Server crea uno automáticamente para cualquier nueva base de datos, junto al primary data file (El MDF). Generalmente las bases de datos contienen solo un archivo Transaction Log, pero es posible implementar múltiples archivos Transaction Log, pero SQL Server siempre escribirá el Log en forma secuencial, ósea de un archivo a la vez, SQL Server no puede y no escribe en paralelo múltiples archivos log y por lo tanto no hay ninguna ventaja en tener múltiples archivos Logs desde la perspectiva del rendimiento.
Siempre que un código T-SQL haga un cambio en un objeto (DDL), o en los datos que este contiene, no solo los datos o el objeto es actualizado en el archivo de Dato también se guarda el detalle de la ejecución como un “log record” en el archivo Transaction Log. Cada “log record” contiene los detalles de un simple y especifico cambio hecho en la base de datos (tal como un insert de una sola fila) o puede requerir una serie de “log record” para describir los efectos de una transacción. Alguno de estas “log record” van almacenar Id de la transacción, cuando inicio y finalizo la transacción, que paginas cambiaron, etc.
1.2. La consistencia transaccional
Vamos a ver qué pasa durante la actualización de múltiples filas en SQL Server. Idealmente, SQL Server va a leer las páginas de datos relevantes desde la data cache, pero tengamos en cuenta que primero retornas las páginas desde el disco si las páginas no están en la cache. Se adquirirá todas las filas, páginas y bloqueo a nivel de tabla necesarios para tomar los datos requeridos y luego comenzara la operación de modificación de datos. Por cada fija afectada a los cambios, se tomara un bloqueo exclusivo, y se modificaran las páginas en memoria que contengan las filas. Este proceso también escribirá una descripción del cambio como un “log record” en memoria en el log Buffer. Cuando todos los cambios son completados, y SQL Server está listo para confirmar la transacción, lo primero que hace es escribir en disco todos los “log record” del buffer, hasta el punto del commit.
Con todas las modificaciones recordadas en el archivo log, SQL Server libera todos los bloqueos y notifica a la sesión que la transacción finalizo con éxito. En este punto los cambios están permanentes y garantizados a persistir ante cualquier falla en el sistema. Tenga en cuenta que SQL Server solo ha escrito en el disco lo relacionado con los “log record” en el archivo log. SQL Server no podrá escribir páginas de datos en disco hasta más tarde, usualmente cuando ocurra la próxima operación de un base de datos checkpoint.

En cada checkpoint, SQL Server escanea la cache de datos y envía todas las paginas sucias de memoria a disco. Se conoce como página sucia, a toda aquella página que sufrió un cambio desde que SQL Server la leyó de disco. Esta tarea de mover las páginas sucias desde memoria a disco no es selectiva, SQL Server mueve todas las paginas marcas como sucias, independientemente de si contiene cambios asociados a las transacciones abiertas (sin confirmar). Sin embargo, el Log Buffer manager siempre garantiza escribir los cambios (log records) en el log de transacción (disco) antes de escribir los cambios en los archivos de datos de la base.
1.3. Transaction Log Backup y Restore
Otro papel que importante que juega el log de Transacciones, es proveer un mecanismo por el cual nosotros podemos restaurar una base de datos a un punto previo en el tiempo, en el cual sucedió un evento de desastre. Con la planificación y una gestión adecuada, podemos usar los estas copias de seguridad del nuestro archivo log para restaurar nuestra base de datos a un estado anterior al que la base de datos se volvió corrupto o inusable.
Como vimos anteriormente, el log de transacciones contiene una serie de “log records”, cada uno describe una sola acción sobre la base de datos, almacenada secuencialmente acorde al momento que las acciones ocurrieron en la base de datos.
Cuando nuestra base de datos esta con figurada en recovery model FULL o BULK_LOGGED, podemos tomar backup de nuestro archivo log. Estos log backups escriben dentro del archivo de backup todos los “log records” que no fueron incluidos en el último log backup.
Durante una operación de restauración, se restaura el más reciente Full Backup de la base de datos seguido por la cadena completa de archivos log backups hasta llegar al punto deseado de restauración de la base de datos.
1.4. Controlando el tamaño del log
Implícitamente la idea de tomar log backups para uso en operaciones de restauración, es la idea que al menos hasta que se produzca una copia del log backup, el log de transacciones deberá retener cada “log record” desde el ultimo log backup. Si SQL Server permitiera que cualquier de los “log records” existentes sean sobre escrito por nuevos “log records”, la secuencia en el log backup podría contener una incompleta descripción de todas las acciones ejecutadas sobre la base de datos desde el ultimo log backup y esto puede ser inusable en cualquier operación de restauración.
Internamente, SQL Server organiza el log de transacciones dividido en secciones, cada una de estas llamadas Virtual Log Files (VLF), y un VLF es la unidad más pequeña en la “reutilización de espacio” en el log. Si un VLF contiene un “log record” que todavía no fue incluido en un Log Backup, se dice que el VLF está Activo y SQL Server no puede reusar su espacio con ningún otro “log record”.
Un punto importante a tener en cuenta, es cuando la base de datos está en un estado de recovery model FULL o BULK_LOGGED, el log backup es la única acción que puede truncar el log. Como tal, el log de transacciones va a mantener todos los las transacciones ejecutada desde el ultimo log backup. SQL Server registrara todas las operaciones en estos recovery models, escribiendo “log records” que describen cada acción ejecutada por cada simple transacción que modifico datos u objetos en la base de datos, y por esta razón es que el archivo de log puede crecer muy rápido, tener un tamaño enorme, ocupando todo el disco que lo contiene, dejar nuestra base de datos en modo solo lectura.
Por este motivo que es muy importante armar una buena política de backup, y ejecutar en forma regular Log Backups, además de nuestro backup full y diferencial.
Cuando un log backup ocurre, cualquier VLF que no contiene transacciones activas será marcado para ser truncado, por los cual SQL Server puede reusar este espacio para nuevos log records.
Cuando nuestra base de datos está en Simple recovery model, el truncado del log puede ocurrir inmediatamente después de que un checkpoint se ejecuta. SQL Server baja las paginas sucias de memoria a disco e inmediatamente después marca los VLFs para ser truncados, así se podrán almacenar nuevos “log records”. Esta es la explicación de por qué no tiene sentido tomar log backups en bases de datos en Simple recovery model.

Columnas y tablas involucradas en una vista

Posted by Miguel Egea | Posted in Relacional, Trucos | Posted on 26-10-2015

1

Hoy vi una pregunta en el foro que me hizo reflexionar, muchas veces parecen las respuestas tan obvias que simplemente las disparamos, pero en este caso recordé una tabla que si bien no tenía muy claro que tuviera lo que yo buscaba, la intuición me decía que  eso tenía que ser así.

La pregunta era escrito en mis palabras la siguiente

Si tengo una vista que involucra a N Tablas, ¿que tablas y que columnas son las que están siendo usadas en la vista?

El caso es que esto me recordó la tabla del sistema sys.sql_Dependencies, no la he usado mucho en mi carrera, pero me dispuse a ver que columnas contenía, encontré esto

 

create table a (id int, id2 int)
create table b (idd int , idd2 int)
go
create view vw as (select * from a cross join b)
go

Después puse esta instrucción para ver que me devolvía.
select object_name(object_id) vista, OBJECT_NAME(referenced_major_id ),(select name from sys.syscolumns cl where cl.id= c.referenced_major_id and colid=referenced_minor_id ),*from sys.sql_dependencies c where object_id=object_id(‘vw’)

y el resultado fue este

dependencies Después de seguir la intuición, que está bien, pero a veces falla, lo que hice fue pensar en que pasaba si el campo era un calculo así que creé una nueva vista de esta forma

create view vw2 as (select id,idd+idd2 result from a cross join b)

lo que quería era ver si realmente me decía las 3columnas o mas…

El resultado fue el esperado, no pongo el pantallazo porque no tiene sentido, es casi idéntico al anterior pero con una fila menos :)

Lo siguiente siempre es ir a MSDN a ver lo que dice de los descriptores de las columnas, y resulta que ahí había una información muy valiosa. El objeto sys.sql_dependencies está “deprecado” o marcado para desaparecer, por lo que usarlo igual no era una buena idea. Bastaron un par de clicks en MSDN para encontrar lo que creo que ncesitamos, y proporcionado por el sistema

select * from sys.dm_sql_referenced_entities(‘dbo.vw2’,‘OBJECT’)

La DMF que nos muestra las entidades referenciadas, que además de las dos columnas nos devuelve las dos entidades como hechos independientes, en el segudo de los casos devuelve una fila para la tabla A, una fila para la tabla B y 3 filas mas una para cada columna, además de eso lo bueno es que también lo hace para procedimientos almacenados y triggers, y demás código.

create procedure dbo.demo

as

begin

select id,id2,idd from a cross join b

return 0

end

go

select * from sys.dm_sql_referenced_entities(‘dbo.demo’,‘OBJECT’)

Es una buena forma quizá de saber en que sitios se hace referencia a una columna o una tabla dentro del código escrito en la base de datos. Quizá escribamos algo sobre esto pronto :)

Aquí teneis el link a MSDN

SSIS : ForEach Loop ejemplos curiosos

Posted by Miguel Egea | Posted in SQL Server Integration Services | Posted on 14-10-2015

0

En el grupo de noticias de SSIS un compañero preguntaba como crear una tabla por cada fichero que se encuentra en un directorio, la tabla tiene que tener el nombre de ese fichero pero una estructura fija.

Este enunciado tal cual es muy específico, pero la forma de resolverlo puede resultar genérica y puede ayudar a comprender algunos aspectos de SSIS que he considerado de interés, de ahí que escriba aquí la solución a este problema.

Lo primero que vamos a hacer es poner un bucle foreach loop tal y como describíamos aquí.

El bucle recorre un directorio, leyendo todos los nombres de fichero, y esos nombres de ficheros son los que vamos a usar para crear la tabla en concreto.

Dentro del bucle lo primero que vamos a hacer es crear una expresión task cuyo valor va a ser

@[User::sql] :=” if (select count(*) from information_schema.tables where table_name ='”+@[User::Fichero]  +”‘)=0 Create table [“+ @[User::Fichero] +”] ( id Int, descripcion Nvarchar(20))”

lo que hace esto es asignar el valor a la variable user::sql, que será la que usemos para lanzar el comando contra la bbdd. Ojo que no estamos teniendo en cuenta el nombre del esquema de la base de datos. Esto normalmente funcionará pero podemos encontrar casos en los que no sea así.

Después vamos a poner un comando SQL con cualquier instrucción, en mi caso puse Select 1, porque la idea es parametrizar ese comando desde las expresiones . la forexpresionma en la que se parametriza es la que puede verse en la imagen.

El resultado es que se crean en mi caso tres tablas que se llaman como los ficheros que hay en el directorio de pruebas.

El aspecto que tiene el paquete es este

bucle

Tras esta funcionalidad en la que hemos creado los objetos vamos a hacer ahora que una consulta de un  origen existente o variable se acabe guardando en un destino variable (el destino será el nombre de la tabla en cuestión).

Para comenzar necesitamos que ya exista una tabla con la misma estructural, el nombre de esa tabla será el valor inicial de la variable fichero. Esto quedaría de la siguiente forma. variabledocumento

Esa variable será la que se asigne a la tabla de destino  con la opción “table name or view name variable”. Lo importante es que SSIS la primera vez ha de validar que el dato es ok. Las siguientes veces ya simplemente funciona cambiando el nombre de la tabla de destino.

Espero que el artículo sirviera a nuestro compañero para resolver su problema

 

 

Cuestión de rendimiento (scans y seeks) y los tipos de datos

Posted by Miguel Egea | Posted in Relacional | Posted on 08-10-2015

0

Es un tema recurrente tener ligeras perdidas de rendimiento con un cambio muy pequeño en una consulta, demasiados factores intervienen para escribirlos en un solo artículo, estadísticas, indices, forma de escribir el query,  pero hay algo en lo que a veces no caemos y …. es realmente malo para el rendimiento

imaginemos estas 3 instrucciones

select * from dbo.FactInternetSales where convert(varchar(10),orderdate,112) between ‘20101229’ and ‘20101231’

select * from dbo.FactInternetSales where cast(orderdate as date) between ‘20101229’ and ‘20101231’

select * from dbo.FactInternetSales where orderdate between ‘20101229’ and ‘20101231’

Las 3 devuelven exactamente los mismos datos  (bueno no es verdad pero mas o menos explico porque no devuelven lo mismo abajo del todo), sin embargo el rendimiento de cada una de las 3 es bastante distinto

Si no hay índice por el campo fecha, las 3 devolverán el mismo plan de ejecución aparentemente.optimizador00 Como podemos ver en la imagen, todas las queries tienen el mismo plan de ejecución y cuestan un 33% del total, sin embargo, la primera tiene además un warning sobre el select. si nos ponemos con el ratón sobre los selects veremos el motivo. El Cast a tipo varchar, ha estimado 9924 filas (mal) mientras que  el resto han estimado un total de 53,9268  casi 54), aunque realmente devuelven 14. Las estimaciones son eso… estimaciones pero no es lo mismo equivocarse en el mismo orden de magnitud que multiplicar el error por más de 100.

optimizador005

El motivo no es otro que al hacer una conversion a un tipo de datos “extraño” SQL Server no puede saber que valores están en el histograma. SQL evita muchas de estas cosas por él mismo, con el optimizador de consultas, por ejemplo el segundo cast no afecta ni a la estimación ni a la ejecución, pero a veces simplemente no puede.

Esto no parece relevante cuando si miramos el resultado en páginas consumidas es el mismo para los 3
optimizador02

(14 row(s) affected)

Table ‘FactInternetSales’. Scan count 1, logical reads 1246, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

Sin embargo es particularmente relevante si creamos un índice por el campo order date

create index ix_date_internetsale on dbo.factinternetsales (orderdate)

Con este índice  el plan de ejecución de la primera instrucción, se mantiene inalterable haciendo un clustered index scan y  costando las mismas 1246 lecturas, mientras que las otras dos ejecuciones hacen planes distintos.

La primera un poco mas sucio por los convert, para cada fila, hace el convert, pero es una operación de procesador, puramente. por eso no se ve en número de lecturas diferencia alguna

(14 row(s) affected)

Table ‘FactInternetSales’. Scan count 1, logical reads 45, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

El tercero, el más limpio queda claro que  hace lo mínimo imprescindible, para leer los datos.

Así pues, cuidado con cast, converts y demás hiervas del lado de los campos. No importan cuando están del lado de las constantes, pero pueden ser letales en rendimiento cuando se encuentran del lado del campo .
(*) y ahora la explicación de porque no dan lo mismo, si el campo order date es de tipo fecha hora, y hay un registro el dia 2010-12-31 después de las 00:00 de la noche, las dos primeras queries lo devolverán mientras que la ultima no. Si quisiéramos que la ultima fuera totalmente equivalente habría que escribirla así

select * from dbo.FactInternetSales where orderdate >=‘20101229’ and orderdate <‘20110101’

 

 

Script para sincronizar Tablas

Posted by Miguel Egea | Posted in Relacional | Posted on 03-10-2015

0

A veces tenemos tablas con la misma estructura en bases de datos diferentes, o bien restauramos una versión de una tabla y queremos que esa información se vuelque. Normalmente hay que insertar los registros que falten, modificar los que sean distintos y borrar los que sobren.
Esta operación que se describe tan fácilmente no es tan sencilla, y desde luego no es genérica. Si la tabla tiene 2 campos, código y descripción , resulta fácil, si la tabla por el contrario tiene 192 campos, se convierte en una tarea insufrible.
Justo el otro dia una compañera en los foros de MSDN tenía esta necesidad. Una réplica que se ha quedado antigua y que no debe reinicializarse, porque borraríamos el destino y podría ser tremendo, necesita sincronizar los datos en el suscriptor. Crear un script para una tabla es fácil, para 192 tablas …es insufrible.

Cuando yo hago este tipo de operaciones, no las hago en T-SQL, las hago en Integration Services, y además las automatizo creando BIML, pero no está de más tener el recurso TSQL así que aquí os comparto el código que he hecho contando también que es lo que pretende cada trozo y como lo he construido. De esta forma no solo está el script sino la forma en la que he pensado cuando lo hacía. Si necesitáis algún cambio en la forma de funcionar, será mucho  más sencillo hacer el cambio si entendéis que hace.

Primer paso, vamos a crear dos bases de datos con dos tablas, y en una rellenamos datos

/****** Object: Database [demo_sync] Script Date: 02-Oct-15 2:29:46 PM ******/
CREATE DATABASE [demo_sync]
CONTAINMENT = NONE
ON PRIMARY
( NAME = N'demo_sync', FILENAME = N'E:\SQL Server\2014\MSSQL12.MSSQLSERVER\MSSQL\DATA\demo_sync.mdf' , SIZE = 3264KB , MAXSIZE = UNLIMITED, FILEGROWTH = 1024KB )
LOG ON
( NAME = N'demo_sync_log', FILENAME = N'E:\SQL Server\2014\MSSQL12.MSSQLSERVER\MSSQL\DATA\demo_sync_log.ldf' , SIZE = 832KB , MAXSIZE = 2048GB , FILEGROWTH = 10%)
GO
CREATE DATABASE [demo]
CONTAINMENT = NONE
ON PRIMARY
( NAME = N'demo', FILENAME = N'E:\SQL Server\2014\MSSQL12.MSSQLSERVER\MSSQL\DATA\demo.mdf' , SIZE = 3264KB , MAXSIZE = UNLIMITED, FILEGROWTH = 1024KB )
LOG ON
( NAME = N'demo_log', FILENAME = N'E:\SQL Server\2014\MSSQL12.MSSQLSERVER\MSSQL\DATA\demo_log.ldf' , SIZE = 832KB , MAXSIZE = 2048GB , FILEGROWTH = 10%)
 
USE [demo]
GO
/****** Object: Table [dbo].[balance] Script Date: 02-Oct-15 2:29:46 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[balance](
[Nº fila] [nvarchar](255) NULL,
[Descripción] [nvarchar](255) NULL,
[Tipo sumatorio] [nvarchar](255) NULL,
[Sumatorio] [float] NULL,
[Tipo] [nvarchar](255) NULL,
[Muestra signo opuesto] [nvarchar](255) NULL,
[Sólo positivo] [nvarchar](255) NULL,
[Cambia signo] [nvarchar](255) NULL,
[Código Areas Totales] [nvarchar](255) NULL,
[Código Proveedores Totales] [nvarchar](255) NULL,
[Total dimensión 3] [nvarchar](255) NULL,
[Total dimensión 4] [nvarchar](255) NULL,
[Muestra] [nvarchar](255) NULL,
[Negrita] [nvarchar](255) NULL,
[Itálica] [nvarchar](255) NULL,
[Subrayar] [nvarchar](255) NULL,
[Muestra signo opuesto2] [nvarchar](255) NULL,
[Cambiar página] [nvarchar](255) NULL,
[Sumatorio char] [nvarchar](255) NULL,
[ID] [int] IDENTITY(1,1) NOT NULL,
PRIMARY KEY CLUSTERED
(
[ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
 
go
USE [demo_sync]
GO
/****** Object: Table [dbo].[balance] Script Date: 02-Oct-15 2:29:46 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[balance](
[Nº fila] [nvarchar](255) NULL,
[Descripción] [nvarchar](255) NULL,
[Tipo sumatorio] [nvarchar](255) NULL,
[Sumatorio] [float] NULL,
[Tipo] [nvarchar](255) NULL,
[Muestra signo opuesto] [nvarchar](255) NULL,
[Sólo positivo] [nvarchar](255) NULL,
[Cambia signo] [nvarchar](255) NULL,
[Código Areas Totales] [nvarchar](255) NULL,
[Código Proveedores Totales] [nvarchar](255) NULL,
[Total dimensión 3] [nvarchar](255) NULL,
[Total dimensión 4] [nvarchar](255) NULL,
[Muestra] [nvarchar](255) NULL,
[Negrita] [nvarchar](255) NULL,
[Itálica] [nvarchar](255) NULL,
[Subrayar] [nvarchar](255) NULL,
[Muestra signo opuesto2] [nvarchar](255) NULL,
[Cambiar página] [nvarchar](255) NULL,
[Sumatorio char] [nvarchar](255) NULL,
[ID] [int] IDENTITY(1,1) NOT NULL,
PRIMARY KEY CLUSTERED
(
[ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
 
GO
SET IDENTITY_INSERT [dbo].[balance] ON
 
GO
INSERT [dbo].[balance] ([Nº fila], [Descripción], [Tipo sumatorio], [Sumatorio], [Tipo], [Muestra signo opuesto], [Sólo positivo], [Cambia signo], [Código Areas Totales], [Código Proveedores Totales], [Total dimensión 3], [Total dimensión 4], [Muestra], [Negrita], [Itálica], [Subrayar], [Muestra signo opuesto2], [Cambiar página], [Sumatorio char], [ID]) VALUES (N'A01&gt;01', N'Investigación', N'Cuentas mayor', 29000, N'Activo', N'No', N'No', N'No', NULL, NULL, NULL, NULL, N'Sí', N'No', N'No', N'No', N'No', N'No', N'29000', 1)
GO
INSERT [dbo].[balance] ([Nº fila], [Descripción], [Tipo sumatorio], [Sumatorio], [Tipo], [Muestra signo opuesto], [Sólo positivo], [Cambia signo], [Código Areas Totales], [Código Proveedores Totales], [Total dimensión 3], [Total dimensión 4], [Muestra], [Negrita], [Itálica], [Subrayar], [Muestra signo opuesto2], [Cambiar página], [Sumatorio char], [ID]) VALUES (N'A01&gt;02', N'Desarrollo', N'Cuentas mayor', NULL, N'Activo', N'No', N'No', N'No', NULL, NULL, NULL, NULL, N'Sí', N'No', N'No', N'No', N'No', N'No', N'', 2)
GO
INSERT [dbo].[balance] ([Nº fila], [Descripción], [Tipo sumatorio], [Sumatorio], [Tipo], [Muestra signo opuesto], [Sólo positivo], [Cambia signo], [Código Areas Totales], [Código Proveedores Totales], [Total dimensión 3], [Total dimensión 4], [Muestra], [Negrita], [Itálica], [Subrayar], [Muestra signo opuesto2], [Cambiar página], [Sumatorio char], [ID]) VALUES (N'A01&gt;03', N'Concesiones', N'Cuentas mayor', NULL, N'Activo', N'No', N'No', N'No', NULL, NULL, NULL, NULL, N'Sí', N'No', N'No', N'No', N'No', N'No', N'', 3)
GO
INSERT [dbo].[balance] ([Nº fila], [Descripción], [Tipo sumatorio], [Sumatorio], [Tipo], [Muestra signo opuesto], [Sólo positivo], [Cambia signo], [Código Areas Totales], [Código Proveedores Totales], [Total dimensión 3], [Total dimensión 4], [Muestra], [Negrita], [Itálica], [Subrayar], [Muestra signo opuesto2], [Cambiar página], [Sumatorio char], [ID]) VALUES (N'A01&gt;04', N'Patentes, licencias, marcas y similares', N'Cuentas mayor', NULL, N'Activo', N'No', N'No', N'No', NULL, NULL, NULL, NULL, N'Sí', N'No', N'No', N'No', N'No', N'No', N'20300|28030', 4)
GO
INSERT [dbo].[balance] ([Nº fila], [Descripción], [Tipo sumatorio], [Sumatorio], [Tipo], [Muestra signo opuesto], [Sólo positivo], [Cambia signo], [Código Areas Totales], [Código Proveedores Totales], [Total dimensión 3], [Total dimensión 4], [Muestra], [Negrita], [Itálica], [Subrayar], [Muestra signo opuesto2], [Cambiar página], [Sumatorio char], [ID]) VALUES (N'A01&gt;05', N'Fondo de comercio', N'Cuentas mayor', 20400, N'Activo', N'No', N'No', N'No', NULL, NULL, NULL, NULL, N'Sí', N'No', N'No', N'No', N'No', N'No', N'20400', 5)
GO
INSERT [dbo].[balance] ([Nº fila], [Descripción], [Tipo sumatorio], [Sumatorio], [Tipo], [Muestra signo opuesto], [Sólo positivo], [Cambia signo], [Código Areas Totales], [Código Proveedores Totales], [Total dimensión 3], [Total dimensión 4], [Muestra], [Negrita], [Itálica], [Subrayar], [Muestra signo opuesto2], [Cambiar página], [Sumatorio char], [ID]) VALUES (N'A01&gt;06', N'Aplicaciones informáticas', N'Cuentas mayor', NULL, N'Activo', N'No', N'No', N'No', NULL, NULL, NULL, NULL, N'Sí', N'No', N'No', N'No', N'No', N'No', N'20600|28060', 6)
GO
INSERT [dbo].[balance] ([Nº fila], [Descripción], [Tipo sumatorio], [Sumatorio], [Tipo], [Muestra signo opuesto], [Sólo positivo], [Cambia signo], [Código Areas Totales], [Código Proveedores Totales], [Total dimensión 3], [Total dimensión 4], [Muestra], [Negrita], [Itálica], [Subrayar], [Muestra signo opuesto2], [Cambiar página], [Sumatorio char], [ID]) VALUES (N'A01&gt;07', N'Dº emisión de gases efecto invernadero', N'Cuentas mayor', NULL, N'Activo', N'No', N'No', N'No', NULL, NULL, NULL, NULL, N'Sí', N'No', N'No', N'No', N'No', N'No', N'', 7)
GO
INSERT [dbo].[balance] ([Nº fila], [Descripción], [Tipo sumatorio], [Sumatorio], [Tipo], [Muestra signo opuesto], [Sólo positivo], [Cambia signo], [Código Areas Totales], [Código Proveedores Totales], [Total dimensión 3], [Total dimensión 4], [Muestra], [Negrita], [Itálica], [Subrayar], [Muestra signo opuesto2], [Cambiar página], [Sumatorio char], [ID]) VALUES (N'A01&gt;08', N'Anticipos', N'Cuentas mayor', 20900, N'Activo', N'No', N'No', N'No', NULL, NULL, NULL, NULL, N'Sí', N'No', N'No', N'No', N'No', N'No', N'20900', 8)
GO
INSERT [dbo].[balance] ([Nº fila], [Descripción], [Tipo sumatorio], [Sumatorio], [Tipo], [Muestra signo opuesto], [Sólo positivo], [Cambia signo], [Código Areas Totales], [Código Proveedores Totales], [Total dimensión 3], [Total dimensión 4], [Muestra], [Negrita], [Itálica], [Subrayar], [Muestra signo opuesto2], [Cambiar página], [Sumatorio char], [ID]) VALUES (N'A01&gt;09', N'Otro inmovilizado intangible', N'Cuentas mayor', NULL, N'Activo', N'No', N'No', N'No', NULL, NULL, NULL, NULL, N'Sí', N'No', N'No', N'No', N'No', N'No', N'20500|28050', 9)
GO
INSERT [dbo].[balance] ([Nº fila], [Descripción], [Tipo sumatorio], [Sumatorio], [Tipo], [Muestra signo opuesto], [Sólo positivo], [Cambia signo], [Código Areas Totales], [Código Proveedores Totales], [Total dimensión 3], [Total dimensión 4], [Muestra], [Negrita], [Itálica], [Subrayar], [Muestra signo opuesto2], [Cambiar página], [Sumatorio char], [ID]) VALUES (N'A01', N'INMOVILIZADO INTANGIBLE', N'Fórmula', NULL, N'Activo', N'No', N'No', N'No', NULL, NULL, NULL, NULL, N'Sí', N'Sí', N'No', N'No', N'No', N'No', N'A01&gt;01+A01&gt;02+A01&gt;03+A01&gt;04+A01&gt;05+A01&gt;06+A01&gt;07+A01&gt;08+A01&gt;09', 10)
GO
INSERT [dbo].[balance] ([Nº fila], [Descripción], [Tipo sumatorio], [Sumatorio], [Tipo], [Muestra signo opuesto], [Sólo positivo], [Cambia signo], [Código Areas Totales], [Código Proveedores Totales], [Total dimensión 3], [Total dimensión 4], [Muestra], [Negrita], [Itálica], [Subrayar], [Muestra signo opuesto2], [Cambiar página], [Sumatorio char], [ID]) VALUES (N'A02&gt;01', N'Terrenos y construcciones', N'Cuentas mayor', NULL, N'Activo', N'No', N'No', N'No', NULL, NULL, NULL, NULL, N'Sí', N'No', N'No', N'No', N'No', N'No', N'21000|21100|28110|29100', 11)
GO
INSERT [dbo].[balance] ([Nº fila], [Descripción], [Tipo sumatorio], [Sumatorio], [Tipo], [Muestra signo opuesto], [Sólo positivo], [Cambia signo], [Código Areas Totales], [Código Proveedores Totales], [Total dimensión 3], [Total dimensión 4], [Muestra], [Negrita], [Itálica], [Subrayar], [Muestra signo opuesto2], [Cambiar página], [Sumatorio char], [ID]) VALUES (N'A02&gt;02', N'Instalaciones técnicas y otro inmoviliz material', N'Cuentas mayor', NULL, N'Activo', N'No', N'No', N'No', NULL, NULL, NULL, NULL, N'Sí', N'No', N'No', N'No', N'No', N'No', N'21200|21201|21300|21400|21500|21501|21600|21700|21800|21900|28120|28121|28130|28140|28150|28160|28170|28180|28190', 12)
GO
INSERT [dbo].[balance] ([Nº fila], [Descripción], [Tipo sumatorio], [Sumatorio], [Tipo], [Muestra signo opuesto], [Sólo positivo], [Cambia signo], [Código Areas Totales], [Código Proveedores Totales], [Total dimensión 3], [Total dimensión 4], [Muestra], [Negrita], [Itálica], [Subrayar], [Muestra signo opuesto2], [Cambiar página], [Sumatorio char], [ID]) VALUES (N'A02&gt;03', N'Inmovilizado en curso y anticipos', N'Cuentas mayor', NULL, N'Activo', N'No', N'No', N'No', NULL, NULL, NULL, NULL, N'Sí', N'No', N'No', N'No', N'No', N'No', N'23000|23100|23200|23201|23300|23700|23900', 13)
GO
INSERT [dbo].[balance] ([Nº fila], [Descripción], [Tipo sumatorio], [Sumatorio], [Tipo], [Muestra signo opuesto], [Sólo positivo], [Cambia signo], [Código Areas Totales], [Código Proveedores Totales], [Total dimensión 3], [Total dimensión 4], [Muestra], [Negrita], [Itálica], [Subrayar], [Muestra signo opuesto2], [Cambiar página], [Sumatorio char], [ID]) VALUES (N'A02', N'INMOVILIZADO MATERIAL', N'Fórmula', NULL, N'Activo', N'No', N'No', N'No', NULL, NULL, NULL, NULL, N'Sí', N'Sí', N'No', N'No', N'No', N'No', N'A02&gt;01+A02&gt;02+A02&gt;03', 14)
GO
INSERT [dbo].[balance] ([Nº fila], [Descripción], [Tipo sumatorio], [Sumatorio], [Tipo], [Muestra signo opuesto], [Sólo positivo], [Cambia signo], [Código Areas Totales], [Código Proveedores Totales], [Total dimensión 3], [Total dimensión 4], [Muestra], [Negrita], [Itálica], [Subrayar], [Muestra signo opuesto2], [Cambiar página], [Sumatorio char], [ID]) VALUES (N'A03&gt;01', N'Terrenos', N'Cuentas mayor', NULL, N'Activo', N'No', N'No', N'No', NULL, NULL, NULL, NULL, N'Sí', N'No', N'No', N'No', N'No', N'No', N'', 15)
GO
INSERT [dbo].[balance] ([Nº fila], [Descripción], [Tipo sumatorio], [Sumatorio], [Tipo], [Muestra signo opuesto], [Sólo positivo], [Cambia signo], [Código Areas Totales], [Código Proveedores Totales], [Total dimensión 3], [Total dimensión 4], [Muestra], [Negrita], [Itálica], [Subrayar], [Muestra signo opuesto2], [Cambiar página], [Sumatorio char], [ID]) VALUES (N'A03&gt;02', N'Construcciones', N'Cuentas mayor', NULL, N'Activo', N'No', N'No', N'No', NULL, NULL, NULL, NULL, N'Sí', N'No', N'No', N'No', N'No', N'No', N'', 16)
GO
INSERT [dbo].[balance] ([Nº fila], [Descripción], [Tipo sumatorio], [Sumatorio], [Tipo], [Muestra signo opuesto], [Sólo positivo], [Cambia signo], [Código Areas Totales], [Código Proveedores Totales], [Total dimensión 3], [Total dimensión 4], [Muestra], [Negrita], [Itálica], [Subrayar], [Muestra signo opuesto2], [Cambiar página], [Sumatorio char], [ID]) VALUES (N'A03&gt;03', N'Inversiones inmobiliarias en curso y anticipos', N'Cuentas mayor', NULL, N'Activo', N'No', N'No', N'No', NULL, NULL, NULL, NULL, N'Sí', N'No', N'No', N'No', N'No', N'No', N'', 17)
GO
INSERT [dbo].[balance] ([Nº fila], [Descripción], [Tipo sumatorio], [Sumatorio], [Tipo], [Muestra signo opuesto], [Sólo positivo], [Cambia signo], [Código Areas Totales], [Código Proveedores Totales], [Total dimensión 3], [Total dimensión 4], [Muestra], [Negrita], [Itálica], [Subrayar], [Muestra signo opuesto2], [Cambiar página], [Sumatorio char], [ID]) VALUES (N'A03', N'INVERSIONES INMOBILIARIAS', N'Fórmula', NULL, N'Activo', N'No', N'No', N'No', NULL, NULL, NULL, NULL, N'Sí', N'Sí', N'No', N'No', N'No', N'No', N'A03&gt;01+A03&gt;02+A03&gt;03', 18)
GO
INSERT [dbo].[balance] ([Nº fila], [Descripción], [Tipo sumatorio], [Sumatorio], [Tipo], [Muestra signo opuesto], [Sólo positivo], [Cambia signo], [Código Areas Totales], [Código Proveedores Totales], [Total dimensión 3], [Total dimensión 4], [Muestra], [Negrita], [Itálica], [Subrayar], [Muestra signo opuesto2], [Cambiar página], [Sumatorio char], [ID]) VALUES (N'A04&gt;01', N'Instrumentos de patrimonio', N'Cuentas mayor', NULL, N'Activo', N'No', N'No', N'No', NULL, NULL, NULL, NULL, N'Sí', N'No', N'No', N'No', N'No', N'No', N'24030|29330', 19)
GO
INSERT [dbo].[balance] ([Nº fila], [Descripción], [Tipo sumatorio], [Sumatorio], [Tipo], [Muestra signo opuesto], [Sólo positivo], [Cambia signo], [Código Areas Totales], [Código Proveedores Totales], [Total dimensión 3], [Total dimensión 4], [Muestra], [Negrita], [Itálica], [Subrayar], [Muestra signo opuesto2], [Cambiar página], [Sumatorio char], [ID]) VALUES (N'A04&gt;02', N'Créditos a empresas', N'Cuentas mayor', 24230, N'Activo', N'No', N'No', N'No', NULL, NULL, NULL, NULL, N'Sí', N'No', N'No', N'No', N'No', N'No', N'24230', 20)
GO
INSERT [dbo].[balance] ([Nº fila], [Descripción], [Tipo sumatorio], [Sumatorio], [Tipo], [Muestra signo opuesto], [Sólo positivo], [Cambia signo], [Código Areas Totales], [Código Proveedores Totales], [Total dimensión 3], [Total dimensión 4], [Muestra], [Negrita], [Itálica], [Subrayar], [Muestra signo opuesto2], [Cambiar página], [Sumatorio char], [ID]) VALUES (N'A04&gt;03', N'Valores representativos de deuda', N'Cuentas mayor', NULL, N'Activo', N'No', N'No', N'No', NULL, NULL, NULL, NULL, N'Sí', N'No', N'No', N'No', N'No', N'No', N'', 21)
GO
INSERT [dbo].[balance] ([Nº fila], [Descripción], [Tipo sumatorio], [Sumatorio], [Tipo], [Muestra signo opuesto], [Sólo positivo], [Cambia signo], [Código Areas Totales], [Código Proveedores Totales], [Total dimensión 3], [Total dimensión 4], [Muestra], [Negrita], [Itálica], [Subrayar], [Muestra signo opuesto2], [Cambiar página], [Sumatorio char], [ID]) VALUES (N'A04&gt;04', N'Derivados', N'Cuentas mayor', NULL, N'Activo', N'No', N'No', N'No', NULL, NULL, NULL, NULL, N'Sí', N'No', N'No', N'No', N'No', N'No', N'', 22)
GO
INSERT [dbo].[balance] ([Nº fila], [Descripción], [Tipo sumatorio], [Sumatorio], [Tipo], [Muestra signo opuesto], [Sólo positivo], [Cambia signo], [Código Areas Totales], [Código Proveedores Totales], [Total dimensión 3], [Total dimensión 4], [Muestra], [Negrita], [Itálica], [Subrayar], [Muestra signo opuesto2], [Cambiar página], [Sumatorio char], [ID]) VALUES (N'A04&gt;05', N'Otros activos financieros', N'Cuentas mayor', NULL, N'Activo', N'No', N'No', N'No', NULL, NULL, NULL, NULL, N'Sí', N'No', N'No', N'No', N'No', N'No', N'', 23)
GO
INSERT [dbo].[balance] ([Nº fila], [Descripción], [Tipo sumatorio], [Sumatorio], [Tipo], [Muestra signo opuesto], [Sólo positivo], [Cambia signo], [Código Areas Totales], [Código Proveedores Totales], [Total dimensión 3], [Total dimensión 4], [Muestra], [Negrita], [Itálica], [Subrayar], [Muestra signo opuesto2], [Cambiar página], [Sumatorio char], [ID]) VALUES (N'A04&gt;06', N'Otras inversiones', N'Cuentas mayor', NULL, N'Activo', N'No', N'No', N'No', NULL, NULL, NULL, NULL, N'Sí', N'No', N'No', N'No', N'No', N'No', N'', 24)
GO
INSERT [dbo].[balance] ([Nº fila], [Descripción], [Tipo sumatorio], [Sumatorio], [Tipo], [Muestra signo opuesto], [Sólo positivo], [Cambia signo], [Código Areas Totales], [Código Proveedores Totales], [Total dimensión 3], [Total dimensión 4], [Muestra], [Negrita], [Itálica], [Subrayar], [Muestra signo opuesto2], [Cambiar página], [Sumatorio char], [ID]) VALUES (N'A04', N'INVERSIONES EN EEGG Y EEAA A LP', N'Fórmula', NULL, N'Activo', N'No', N'No', N'No', NULL, NULL, NULL, NULL, N'Sí', N'Sí', N'No', N'No', N'No', N'No', N'A04&gt;01+A04&gt;02+A04&gt;03+A04&gt;04+A04&gt;05+A04&gt;06', 25)
GO
INSERT [dbo].[balance] ([Nº fila], [Descripción], [Tipo sumatorio], [Sumatorio], [Tipo], [Muestra signo opuesto], [Sólo positivo], [Cambia signo], [Código Areas Totales], [Código Proveedores Totales], [Total dimensión 3], [Total dimensión 4], [Muestra], [Negrita], [Itálica], [Subrayar], [Muestra signo opuesto2], [Cambiar página], [Sumatorio char], [ID]) VALUES (N'A05&gt;01', N'Instrumentos de patrimonio', N'Cuentas mayor', 25000, N'Activo', N'No', N'No', N'No', NULL, NULL, NULL, NULL, N'Sí', N'No', N'No', N'No', N'No', N'No', N'25000', 26)
GO
INSERT [dbo].[balance] ([Nº fila], [Descripción], [Tipo sumatorio], [Sumatorio], [Tipo], [Muestra signo opuesto], [Sólo positivo], [Cambia signo], [Código Areas Totales], [Código Proveedores Totales], [Total dimensión 3], [Total dimensión 4], [Muestra], [Negrita], [Itálica], [Subrayar], [Muestra signo opuesto2], [Cambiar página], [Sumatorio char], [ID]) VALUES (N'A05&gt;02', N'Créditos a terceros', N'Cuentas mayor', NULL, N'Activo', N'No', N'No', N'No', NULL, NULL, NULL, NULL, N'Sí', N'No', N'No', N'No', N'No', N'No', N'25200|25300|25400|29800', 27)
GO
INSERT [dbo].[balance] ([Nº fila], [Descripción], [Tipo sumatorio], [Sumatorio], [Tipo], [Muestra signo opuesto], [Sólo positivo], [Cambia signo], [Código Areas Totales], [Código Proveedores Totales], [Total dimensión 3], [Total dimensión 4], [Muestra], [Negrita], [Itálica], [Subrayar], [Muestra signo opuesto2], [Cambiar página], [Sumatorio char], [ID]) VALUES (N'A05&gt;03', N'Valores representativos de deuda', N'Cuentas mayor', NULL, N'Activo', N'No', N'No', N'No', NULL, NULL, NULL, NULL, N'Sí', N'No', N'No', N'No', N'No', N'No', N'25100|29700', 28)
GO
INSERT [dbo].[balance] ([Nº fila], [Descripción], [Tipo sumatorio], [Sumatorio], [Tipo], [Muestra signo opuesto], [Sólo positivo], [Cambia signo], [Código Areas Totales], [Código Proveedores Totales], [Total dimensión 3], [Total dimensión 4], [Muestra], [Negrita], [Itálica], [Subrayar], [Muestra signo opuesto2], [Cambiar página], [Sumatorio char], [ID]) VALUES (N'A05&gt;04', N'Derivados', N'Cuentas mayor', NULL, N'Activo', N'No', N'No', N'No', NULL, NULL, NULL, NULL, N'Sí', N'No', N'No', N'No', N'No', N'No', N'', 29)
GO
INSERT [dbo].[balance] ([Nº fila], [Descripción], [Tipo sumatorio], [Sumatorio], [Tipo], [Muestra signo opuesto], [Sólo positivo], [Cambia signo], [Código Areas Totales], [Código Proveedores Totales], [Total dimensión 3], [Total dimensión 4], [Muestra], [Negrita], [Itálica], [Subrayar], [Muestra signo opuesto2], [Cambiar página], [Sumatorio char], [ID]) VALUES (N'A05&gt;05', N'Otros activos financieros', N'Cuentas mayor', NULL, N'Activo', N'No', N'No', N'No', NULL, NULL, NULL, NULL, N'Sí', N'No', N'No', N'No', N'No', N'No', N'25800|26000|26500', 30)
GO
INSERT [dbo].[balance] ([Nº fila], [Descripción], [Tipo sumatorio], [Sumatorio], [Tipo], [Muestra signo opuesto], [Sólo positivo], [Cambia signo], [Código Areas Totales], [Código Proveedores Totales], [Total dimensión 3], [Total dimensión 4], [Muestra], [Negrita], [Itálica], [Subrayar], [Muestra signo opuesto2], [Cambiar página], [Sumatorio char], [ID]) VALUES (N'A05&gt;06', N'Otras inversiones', N'Cuentas mayor', NULL, N'Activo', N'No', N'No', N'No', NULL, NULL, NULL, NULL, N'Sí', N'No', N'No', N'No', N'No', N'No', N'', 31)
GO
INSERT [dbo].[balance] ([Nº fila], [Descripción], [Tipo sumatorio], [Sumatorio], [Tipo], [Muestra signo opuesto], [Sólo positivo], [Cambia signo], [Código Areas Totales], [Código Proveedores Totales], [Total dimensión 3], [Total dimensión 4], [Muestra], [Negrita], [Itálica], [Subrayar], [Muestra signo opuesto2], [Cambiar página], [Sumatorio char], [ID]) VALUES (N'A05', N'INVERSIONES FINANCIERAS A LARGO PLAZO', N'Fórmula', NULL, N'Activo', N'No', N'No', N'No', NULL, NULL, NULL, NULL, N'Sí', N'Sí', N'No', N'No', N'No', N'No', N'A05&gt;01+A05&gt;02+A05&gt;03+A05&gt;04+A05&gt;05+A05&gt;06', 32)
GO
INSERT [dbo].[balance] ([Nº fila], [Descripción], [Tipo sumatorio], [Sumatorio], [Tipo], [Muestra signo opuesto], [Sólo positivo], [Cambia signo], [Código Areas Totales], [Código Proveedores Totales], [Total dimensión 3], [Total dimensión 4], [Muestra], [Negrita], [Itálica], [Subrayar], [Muestra signo opuesto2], [Cambiar página], [Sumatorio char], [ID]) VALUES (N'A06&gt;01', N'Clientes por vtas y prest. serv. (sup. a ciclo ex)', N'Cuentas mayor', NULL, N'Activo', N'No', N'No', N'No', NULL, NULL, NULL, NULL, N'Sí', N'No', N'No', N'No', N'No', N'No', N'', 33)
GO
INSERT [dbo].[balance] ([Nº fila], [Descripción], [Tipo sumatorio], [Sumatorio], [Tipo], [Muestra signo opuesto], [Sólo positivo], [Cambia signo], [Código Areas Totales], [Código Proveedores Totales], [Total dimensión 3], [Total dimensión 4], [Muestra], [Negrita], [Itálica], [Subrayar], [Muestra signo opuesto2], [Cambiar página], [Sumatorio char], [ID]) VALUES (N'A06&gt;02', N'Clientes, EEGG y EEAA (sup. a ciclo explot.)', N'Cuentas mayor', NULL, N'Activo', N'No', N'No', N'No', NULL, NULL, NULL, NULL, N'Sí', N'No', N'No', N'No', N'No', N'No', N'', 34)
GO
INSERT [dbo].[balance] ([Nº fila], [Descripción], [Tipo sumatorio], [Sumatorio], [Tipo], [Muestra signo opuesto], [Sólo positivo], [Cambia signo], [Código Areas Totales], [Código Proveedores Totales], [Total dimensión 3], [Total dimensión 4], [Muestra], [Negrita], [Itálica], [Subrayar], [Muestra signo opuesto2], [Cambiar página], [Sumatorio char], [ID]) VALUES (N'A06&gt;03', N'Otros créditos con las Administraciones Públicas', N'Cuentas mayor', NULL, N'Activo', N'No', N'No', N'No', NULL, NULL, NULL, NULL, N'Sí', N'No', N'No', N'No', N'No', N'No', N'', 35)
GO
INSERT [dbo].[balance] ([Nº fila], [Descripción], [Tipo sumatorio], [Sumatorio], [Tipo], [Muestra signo opuesto], [Sólo positivo], [Cambia signo], [Código Areas Totales], [Código Proveedores Totales], [Total dimensión 3], [Total dimensión 4], [Muestra], [Negrita], [Itálica], [Subrayar], [Muestra signo opuesto2], [Cambiar página], [Sumatorio char], [ID]) VALUES (N'A06&gt;04', N'Deudores varios', N'Cuentas mayor', NULL, N'Activo', N'No', N'No', N'No', NULL, NULL, NULL, NULL, N'Sí', N'No', N'No', N'No', N'No', N'No', N'', 36)
GO
INSERT [dbo].[balance] ([Nº fila], [Descripción], [Tipo sumatorio], [Sumatorio], [Tipo], [Muestra signo opuesto], [Sólo positivo], [Cambia signo], [Código Areas Totales], [Código Proveedores Totales], [Total dimensión 3], [Total dimensión 4], [Muestra], [Negrita], [Itálica], [Subrayar], [Muestra signo opuesto2], [Cambiar página], [Sumatorio char], [ID]) VALUES (N'A06', N'DEUDORES COMERCIALES Y OTRAS CUENTAS A COBRAR LP', N'Fórmula', NULL, N'Activo', N'No', N'No', N'No', NULL, NULL, NULL, NULL, N'Sí', N'Sí', N'No', N'No', N'No', N'No', N'A06&gt;01+A06&gt;02+A06&gt;03+A06&gt;04', 37)
GO
INSERT [dbo].[balance] ([Nº fila], [Descripción], [Tipo sumatorio], [Sumatorio], [Tipo], [Muestra signo opuesto], [Sólo positivo], [Cambia signo], [Código Areas Totales], [Código Proveedores Totales], [Total dimensión 3], [Total dimensión 4], [Muestra], [Negrita], [Itálica], [Subrayar], [Muestra signo opuesto2], [Cambiar página], [Sumatorio char], [ID]) VALUES (N'A07', N'ACTIVOS POR IMPUESTO DIFERIDO', N'Cuentas mayor', NULL, N'Activo', N'No', N'No', N'No', NULL, NULL, NULL, NULL, N'Sí', N'Sí', N'No', N'No', N'No', N'No', N'47400|47450', 38)
GO
INSERT [dbo].[balance] ([Nº fila], [Descripción], [Tipo sumatorio], [Sumatorio], [Tipo], [Muestra signo opuesto], [Sólo positivo], [Cambia signo], [Código Areas Totales], [Código Proveedores Totales], [Total dimensión 3], [Total dimensión 4], [Muestra], [Negrita], [Itálica], [Subrayar], [Muestra signo opuesto2], [Cambiar página], [Sumatorio char], [ID]) VALUES (N'A08', N'PERIODIFICACIONES A LARGO PLAZO', N'Cuentas mayor', NULL, N'Activo', N'No', N'No', N'No', NULL, NULL, NULL, NULL, N'Sí', N'Sí', N'No', N'No', N'No', N'No', N'', 39)
GO
INSERT [dbo].[balance] ([Nº fila], [Descripción], [Tipo sumatorio], [Sumatorio], [Tipo], [Muestra signo opuesto], [Sólo positivo], [Cambia signo], [Código Areas Totales], [Código Proveedores Totales], [Total dimensión 3], [Total dimensión 4], [Muestra], [Negrita], [Itálica], [Subrayar], [Muestra signo opuesto2], [Cambiar página], [Sumatorio char], [ID]) VALUES (N'A', N'ACTIVO NO CORRIENTE', N'Fórmula', NULL, N'Activo', N'No', N'No', N'No', NULL, NULL, NULL, NULL, N'Sí', N'Sí', N'No', N'No', N'No', N'No', N'A01+A02+A03+A04+A05+A06+A07+A08', 40)
GO
INSERT [dbo].[balance] ([Nº fila], [Descripción], [Tipo sumatorio], [Sumatorio], [Tipo], [Muestra signo opuesto], [Sólo positivo], [Cambia signo], [Código Areas Totales], [Código Proveedores Totales], [Total dimensión 3], [Total dimensión 4], [Muestra], [Negrita], [Itálica], [Subrayar], [Muestra signo opuesto2], [Cambiar página], [Sumatorio char], [ID]) VALUES (N'B01', N'ACTIVOS NO CORRIENTES MANTENIDOS PARA LA VENTA', N'Cuentas mayor', NULL, N'Activo', N'No', N'No', N'No', NULL, NULL, NULL, NULL, N'Sí', N'Sí', N'No', N'No', N'No', N'No', N'', 41)
GO
INSERT [dbo].[balance] ([Nº fila], [Descripción], [Tipo sumatorio], [Sumatorio], [Tipo], [Muestra signo opuesto], [Sólo positivo], [Cambia signo], [Código Areas Totales], [Código Proveedores Totales], [Total dimensión 3], [Total dimensión 4], [Muestra], [Negrita], [Itálica], [Subrayar], [Muestra signo opuesto2], [Cambiar página], [Sumatorio char], [ID]) VALUES (N'B02&gt;01', N'Comerciales', N'Cuentas mayor', 30000, N'Activo', N'No', N'No', N'No', NULL, NULL, NULL, NULL, N'Sí', N'No', N'No', N'No', N'No', N'No', N'30000', 42)
GO
INSERT [dbo].[balance] ([Nº fila], [Descripción], [Tipo sumatorio], [Sumatorio], [Tipo], [Muestra signo opuesto], [Sólo positivo], [Cambia signo], [Código Areas Totales], [Código Proveedores Totales], [Total dimensión 3], [Total dimensión 4], [Muestra], [Negrita], [Itálica], [Subrayar], [Muestra signo opuesto2], [Cambiar página], [Sumatorio char], [ID]) VALUES (N'B02&gt;02', N'Materias primas y otros aprovisionamientos', N'Cuentas mayor', NULL, N'Activo', N'No', N'No', N'No', NULL, NULL, NULL, NULL, N'Sí', N'No', N'No', N'No', N'No', N'No', N'31000|31100|32000|32200|32500|32600|32800|32900|32901|39100|39200', 43)
GO
INSERT [dbo].[balance] ([Nº fila], [Descripción], [Tipo sumatorio], [Sumatorio], [Tipo], [Muestra signo opuesto], [Sólo positivo], [Cambia signo], [Código Areas Totales], [Código Proveedores Totales], [Total dimensión 3], [Total dimensión 4], [Muestra], [Negrita], [Itálica], [Subrayar], [Muestra signo opuesto2], [Cambiar página], [Sumatorio char], [ID]) VALUES (N'B02&gt;03', N'Productos en curso ciclo corto', N'Cuentas mayor', NULL, N'Activo', N'No', N'No', N'No', NULL, NULL, NULL, NULL, N'Sí', N'No', N'No', N'No', N'No', N'No', N'33000|39300', 44)
GO
INSERT [dbo].[balance] ([Nº fila], [Descripción], [Tipo sumatorio], [Sumatorio], [Tipo], [Muestra signo opuesto], [Sólo positivo], [Cambia signo], [Código Areas Totales], [Código Proveedores Totales], [Total dimensión 3], [Total dimensión 4], [Muestra], [Negrita], [Itálica], [Subrayar], [Muestra signo opuesto2], [Cambiar página], [Sumatorio char], [ID]) VALUES (N'B02&gt;04', N'Productos en curso ciclo largo', N'Cuentas mayor', NULL, N'Activo', N'No', N'No', N'No', NULL, NULL, NULL, NULL, N'Sí', N'No', N'No', N'No', N'No', N'No', N'', 45)
GO
INSERT [dbo].[balance] ([Nº fila], [Descripción], [Tipo sumatorio], [Sumatorio], [Tipo], [Muestra signo opuesto], [Sólo positivo], [Cambia signo], [Código Areas Totales], [Código Proveedores Totales], [Total dimensión 3], [Total dimensión 4], [Muestra], [Negrita], [Itálica], [Subrayar], [Muestra signo opuesto2], [Cambiar página], [Sumatorio char], [ID]) VALUES (N'B02&gt;05', N'Productos terminados ciclo corto', N'Cuentas mayor', NULL, N'Activo', N'No', N'No', N'No', NULL, NULL, NULL, NULL, N'Sí', N'No', N'No', N'No', N'No', N'No', N'35000|39500', 46)
GO
INSERT [dbo].[balance] ([Nº fila], [Descripción], [Tipo sumatorio], [Sumatorio], [Tipo], [Muestra signo opuesto], [Sólo positivo], [Cambia signo], [Código Areas Totales], [Código Proveedores Totales], [Total dimensión 3], [Total dimensión 4], [Muestra], [Negrita], [Itálica], [Subrayar], [Muestra signo opuesto2], [Cambiar página], [Sumatorio char], [ID]) VALUES (N'B02&gt;06', N'Productos terminados ciclo largo', N'Cuentas mayor', 36000, N'Activo', N'No', N'No', N'No', NULL, NULL, NULL, NULL, N'Sí', N'No', N'No', N'No', N'No', N'No', N'36000', 47)
GO
INSERT [dbo].[balance] ([Nº fila], [Descripción], [Tipo sumatorio], [Sumatorio], [Tipo], [Muestra signo opuesto], [Sólo positivo], [Cambia signo], [Código Areas Totales], [Código Proveedores Totales], [Total dimensión 3], [Total dimensión 4], [Muestra], [Negrita], [Itálica], [Subrayar], [Muestra signo opuesto2], [Cambiar página], [Sumatorio char], [ID]) VALUES (N'B02&gt;07', N'Subproductos, residuos y materiales recuperados', N'Cuentas mayor', 36000, N'Activo', N'No', N'No', N'No', NULL, NULL, NULL, NULL, N'Sí', N'No', N'No', N'No', N'No', N'No', N'36000', 48)
GO
INSERT [dbo].[balance] ([Nº fila], [Descripción], [Tipo sumatorio], [Sumatorio], [Tipo], [Muestra signo opuesto], [Sólo positivo], [Cambia signo], [Código Areas Totales], [Código Proveedores Totales], [Total dimensión 3], [Total dimensión 4], [Muestra], [Negrita], [Itálica], [Subrayar], [Muestra signo opuesto2], [Cambiar página], [Sumatorio char], [ID]) VALUES (N'B02&gt;08', N'Anticipos a proveedores', N'Cuentas mayor', 40700, N'Activo', N'No', N'No', N'No', NULL, NULL, NULL, NULL, N'Sí', N'No', N'No', N'No', N'No', N'No', N'40700', 49)
GO
INSERT [dbo].[balance] ([Nº fila], [Descripción], [Tipo sumatorio], [Sumatorio], [Tipo], [Muestra signo opuesto], [Sólo positivo], [Cambia signo], [Código Areas Totales], [Código Proveedores Totales], [Total dimensión 3], [Total dimensión 4], [Muestra], [Negrita], [Itálica], [Subrayar], [Muestra signo opuesto2], [Cambiar página], [Sumatorio char], [ID]) VALUES (N'B02', N'EXISTENCIAS', N'Fórmula', NULL, N'Activo', N'No', N'No', N'No', NULL, NULL, NULL, NULL, N'Sí', N'Sí', N'No', N'No', N'No', N'No', N'B02&gt;01+B02&gt;02+B02&gt;03+B02&gt;04+B02&gt;05+B02&gt;06+B02&gt;07+B02&gt;08', 50)
GO
INSERT [dbo].[balance] ([Nº fila], [Descripción], [Tipo sumatorio], [Sumatorio], [Tipo], [Muestra signo opuesto], [Sólo positivo], [Cambia signo], [Código Areas Totales], [Código Proveedores Totales], [Total dimensión 3], [Total dimensión 4], [Muestra], [Negrita], [Itálica], [Subrayar], [Muestra signo opuesto2], [Cambiar página], [Sumatorio char], [ID]) VALUES (N'B03&gt;01', N'Clientes por ventas y prestaciones de servicios cp', N'Cuentas mayor', NULL, N'Activo', N'No', N'No', N'No', NULL, NULL, NULL, NULL, N'Sí', N'No', N'No', N'No', N'No', N'No', N'43000|43001|43003|43004|43005|43006|43007|43008|43009|43040|43090|43110|43600|43809|49000', 51)
GO
INSERT [dbo].[balance] ([Nº fila], [Descripción], [Tipo sumatorio], [Sumatorio], [Tipo], [Muestra signo opuesto], [Sólo positivo], [Cambia signo], [Código Areas Totales], [Código Proveedores Totales], [Total dimensión 3], [Total dimensión 4], [Muestra], [Negrita], [Itálica], [Subrayar], [Muestra signo opuesto2], [Cambiar página], [Sumatorio char], [ID]) VALUES (N'B03&gt;02', N'Clientes por ventas y prestaciones de servicios lp', N'Cuentas mayor', NULL, N'Activo', N'No', N'No', N'No', NULL, NULL, NULL, NULL, N'Sí', N'No', N'No', N'No', N'No', N'No', N'', 52)
GO
INSERT [dbo].[balance] ([Nº fila], [Descripción], [Tipo sumatorio], [Sumatorio], [Tipo], [Muestra signo opuesto], [Sólo positivo], [Cambia signo], [Código Areas Totales], [Código Proveedores Totales], [Total dimensión 3], [Total dimensión 4], [Muestra], [Negrita], [Itálica], [Subrayar], [Muestra signo opuesto2], [Cambiar página], [Sumatorio char], [ID]) VALUES (N'B03&gt;03', N'Clientes, empresas del grupo y asociadas corto p.', N'Cuentas mayor', NULL, N'Activo', N'No', N'No', N'No', NULL, NULL, NULL, NULL, N'Sí', N'No', N'No', N'No', N'No', N'No', N'43300|43340|44300', 53)
GO
INSERT [dbo].[balance] ([Nº fila], [Descripción], [Tipo sumatorio], [Sumatorio], [Tipo], [Muestra signo opuesto], [Sólo positivo], [Cambia signo], [Código Areas Totales], [Código Proveedores Totales], [Total dimensión 3], [Total dimensión 4], [Muestra], [Negrita], [Itálica], [Subrayar], [Muestra signo opuesto2], [Cambiar página], [Sumatorio char], [ID]) VALUES (N'B03&gt;04', N'Clientes, empresas del grupo y asociadas largo p.', N'Cuentas mayor', NULL, N'Activo', N'No', N'No', N'No', NULL, NULL, NULL, NULL, N'Sí', N'No', N'No', N'No', N'No', N'No', N'', 54)
GO
INSERT [dbo].[balance] ([Nº fila], [Descripción], [Tipo sumatorio], [Sumatorio], [Tipo], [Muestra signo opuesto], [Sólo positivo], [Cambia signo], [Código Areas Totales], [Código Proveedores Totales], [Total dimensión 3], [Total dimensión 4], [Muestra], [Negrita], [Itálica], [Subrayar], [Muestra signo opuesto2], [Cambiar página], [Sumatorio char], [ID]) VALUES (N'B03&gt;05', N'Deudores varios', N'Cuentas mayor', NULL, N'Activo', N'No', N'No', N'No', NULL, NULL, NULL, NULL, N'Sí', N'No', N'No', N'No', N'No', N'No', N'44000|44040', 55)
GO
INSERT [dbo].[balance] ([Nº fila], [Descripción], [Tipo sumatorio], [Sumatorio], [Tipo], [Muestra signo opuesto], [Sólo positivo], [Cambia signo], [Código Areas Totales], [Código Proveedores Totales], [Total dimensión 3], [Total dimensión 4], [Muestra], [Negrita], [Itálica], [Subrayar], [Muestra signo opuesto2], [Cambiar página], [Sumatorio char], [ID]) VALUES (N'B03&gt;06', N'Personal', N'Cuentas mayor', 46000, N'Activo', N'No', N'No', N'No', NULL, NULL, NULL, NULL, N'Sí', N'No', N'No', N'No', N'No', N'No', N'46000', 56)
GO
INSERT [dbo].[balance] ([Nº fila], [Descripción], [Tipo sumatorio], [Sumatorio], [Tipo], [Muestra signo opuesto], [Sólo positivo], [Cambia signo], [Código Areas Totales], [Código Proveedores Totales], [Total dimensión 3], [Total dimensión 4], [Muestra], [Negrita], [Itálica], [Subrayar], [Muestra signo opuesto2], [Cambiar página], [Sumatorio char], [ID]) VALUES (N'B03&gt;07', N'Activos por impuesto corriente', N'Cuentas mayor', 47090, N'Activo', N'No', N'No', N'No', NULL, NULL, NULL, NULL, N'Sí', N'No', N'No', N'No', N'No', N'No', N'47090', 57)
GO
INSERT [dbo].[balance] ([Nº fila], [Descripción], [Tipo sumatorio], [Sumatorio], [Tipo], [Muestra signo opuesto], [Sólo positivo], [Cambia signo], [Código Areas Totales], [Código Proveedores Totales], [Total dimensión 3], [Total dimensión 4], [Muestra], [Negrita], [Itálica], [Subrayar], [Muestra signo opuesto2], [Cambiar página], [Sumatorio char], [ID]) VALUES (N'B03&gt;08', N'Otros créditos con las Administraciones Públicas', N'Cuentas mayor', NULL, N'Activo', N'No', N'No', N'No', NULL, NULL, NULL, NULL, N'Sí', N'No', N'No', N'No', N'No', N'No', N'47000|47080|47100|47200|47300', 58)
GO
INSERT [dbo].[balance] ([Nº fila], [Descripción], [Tipo sumatorio], [Sumatorio], [Tipo], [Muestra signo opuesto], [Sólo positivo], [Cambia signo], [Código Areas Totales], [Código Proveedores Totales], [Total dimensión 3], [Total dimensión 4], [Muestra], [Negrita], [Itálica], [Subrayar], [Muestra signo opuesto2], [Cambiar página], [Sumatorio char], [ID]) VALUES (N'B03&gt;09', N'Accionistas (socios) por desembolsos exigidos', N'Cuentas mayor', 55800, N'Activo', N'No', N'No', N'No', NULL, NULL, NULL, NULL, N'Sí', N'No', N'No', N'No', N'No', N'No', N'55800', 59)
GO
INSERT [dbo].[balance] ([Nº fila], [Descripción], [Tipo sumatorio], [Sumatorio], [Tipo], [Muestra signo opuesto], [Sólo positivo], [Cambia signo], [Código Areas Totales], [Código Proveedores Totales], [Total dimensión 3], [Total dimensión 4], [Muestra], [Negrita], [Itálica], [Subrayar], [Muestra signo opuesto2], [Cambiar página], [Sumatorio char], [ID]) VALUES (N'B03', N'DEUDORES COMERCIALES Y OTRAS CUENTAS A COBRAR', N'Fórmula', NULL, N'Activo', N'No', N'No', N'No', NULL, NULL, NULL, NULL, N'Sí', N'Sí', N'No', N'No', N'No', N'No', N'B03&gt;01+B03&gt;02+B03&gt;03+B03&gt;04+B03&gt;05+B03&gt;06+B03&gt;07+B03&gt;08+B03&gt;09', 60)
GO
INSERT [dbo].[balance] ([Nº fila], [Descripción], [Tipo sumatorio], [Sumatorio], [Tipo], [Muestra signo opuesto], [Sólo positivo], [Cambia signo], [Código Areas Totales], [Código Proveedores Totales], [Total dimensión 3], [Total dimensión 4], [Muestra], [Negrita], [Itálica], [Subrayar], [Muestra signo opuesto2], [Cambiar página], [Sumatorio char], [ID]) VALUES (N'B04&gt;01', N'Instrumentos de patrimonio', N'Cuentas mayor', NULL, N'Activo', N'No', N'No', N'No', NULL, NULL, NULL, NULL, N'Sí', N'No', N'No', N'No', N'No', N'No', N'', 61)
GO
INSERT [dbo].[balance] ([Nº fila], [Descripción], [Tipo sumatorio], [Sumatorio], [Tipo], [Muestra signo opuesto], [Sólo positivo], [Cambia signo], [Código Areas Totales], [Código Proveedores Totales], [Total dimensión 3], [Total dimensión 4], [Muestra], [Negrita], [Itálica], [Subrayar], [Muestra signo opuesto2], [Cambiar página], [Sumatorio char], [ID]) VALUES (N'B04&gt;02', N'Créditos a empresas', N'Cuentas mayor', NULL, N'Activo', N'No', N'No', N'No', NULL, NULL, NULL, NULL, N'Sí', N'No', N'No', N'No', N'No', N'No', N'53230|54400', 62)
GO
INSERT [dbo].[balance] ([Nº fila], [Descripción], [Tipo sumatorio], [Sumatorio], [Tipo], [Muestra signo opuesto], [Sólo positivo], [Cambia signo], [Código Areas Totales], [Código Proveedores Totales], [Total dimensión 3], [Total dimensión 4], [Muestra], [Negrita], [Itálica], [Subrayar], [Muestra signo opuesto2], [Cambiar página], [Sumatorio char], [ID]) VALUES (N'B04&gt;03', N'Valores representativos de deuda', N'Cuentas mayor', NULL, N'Activo', N'No', N'No', N'No', NULL, NULL, NULL, NULL, N'Sí', N'No', N'No', N'No', N'No', N'No', N'', 63)
GO
INSERT [dbo].[balance] ([Nº fila], [Descripción], [Tipo sumatorio], [Sumatorio], [Tipo], [Muestra signo opuesto], [Sólo positivo], [Cambia signo], [Código Areas Totales], [Código Proveedores Totales], [Total dimensión 3], [Total dimensión 4], [Muestra], [Negrita], [Itálica], [Subrayar], [Muestra signo opuesto2], [Cambiar página], [Sumatorio char], [ID]) VALUES (N'B04&gt;04', N'Derivados', N'Cuentas mayor', NULL, N'Activo', N'No', N'No', N'No', NULL, NULL, NULL, NULL, N'Sí', N'No', N'No', N'No', N'No', N'No', N'', 64)
GO
INSERT [dbo].[balance] ([Nº fila], [Descripción], [Tipo sumatorio], [Sumatorio], [Tipo], [Muestra signo opuesto], [Sólo positivo], [Cambia signo], [Código Areas Totales], [Código Proveedores Totales], [Total dimensión 3], [Total dimensión 4], [Muestra], [Negrita], [Itálica], [Subrayar], [Muestra signo opuesto2], [Cambiar página], [Sumatorio char], [ID]) VALUES (N'B04&gt;05', N'Otros activos financieros', N'Cuentas mayor', NULL, N'Activo', N'No', N'No', N'No', NULL, NULL, NULL, NULL, N'Sí', N'No', N'No', N'No', N'No', N'No', N'', 65)
GO
INSERT [dbo].[balance] ([Nº fila], [Descripción], [Tipo sumatorio], [Sumatorio], [Tipo], [Muestra signo opuesto], [Sólo positivo], [Cambia signo], [Código Areas Totales], [Código Proveedores Totales], [Total dimensión 3], [Total dimensión 4], [Muestra], [Negrita], [Itálica], [Subrayar], [Muestra signo opuesto2], [Cambiar página], [Sumatorio char], [ID]) VALUES (N'B04&gt;06', N'Otras inversiones', N'Cuentas mayor', NULL, N'Activo', N'No', N'No', N'No', NULL, NULL, NULL, NULL, N'Sí', N'No', N'No', N'No', N'No', N'No', N'', 66)
GO
INSERT [dbo].[balance] ([Nº fila], [Descripción], [Tipo sumatorio], [Sumatorio], [Tipo], [Muestra signo opuesto], [Sólo positivo], [Cambia signo], [Código Areas Totales], [Código Proveedores Totales], [Total dimensión 3], [Total dimensión 4], [Muestra], [Negrita], [Itálica], [Subrayar], [Muestra signo opuesto2], [Cambiar página], [Sumatorio char], [ID]) VALUES (N'B04', N'INVERSIONES EN EEGG Y EEAA A CP', N'Fórmula', NULL, N'Activo', N'No', N'No', N'No', NULL, NULL, NULL, NULL, N'Sí', N'Sí', N'No', N'No', N'No', N'No', N'B04&gt;01+B04&gt;02+B04&gt;03+B04&gt;04+B04&gt;05+B04&gt;06', 67)
GO
INSERT [dbo].[balance] ([Nº fila], [Descripción], [Tipo sumatorio], [Sumatorio], [Tipo], [Muestra signo opuesto], [Sólo positivo], [Cambia signo], [Código Areas Totales], [Código Proveedores Totales], [Total dimensión 3], [Total dimensión 4], [Muestra], [Negrita], [Itálica], [Subrayar], [Muestra signo opuesto2], [Cambiar página], [Sumatorio char], [ID]) VALUES (N'B05&gt;01', N'Instrumentos de patrimonio', N'Cuentas mayor', NULL, N'Activo', N'No', N'No', N'No', NULL, NULL, NULL, NULL, N'Sí', N'No', N'No', N'No', N'No', N'No', N'54000|54900', 68)
GO
INSERT [dbo].[balance] ([Nº fila], [Descripción], [Tipo sumatorio], [Sumatorio], [Tipo], [Muestra signo opuesto], [Sólo positivo], [Cambia signo], [Código Areas Totales], [Código Proveedores Totales], [Total dimensión 3], [Total dimensión 4], [Muestra], [Negrita], [Itálica], [Subrayar], [Muestra signo opuesto2], [Cambiar página], [Sumatorio char], [ID]) VALUES (N'B05&gt;02', N'Créditos a empresas', N'Cuentas mayor', NULL, N'Activo', N'No', N'No', N'No', NULL, NULL, NULL, NULL, N'Sí', N'No', N'No', N'No', N'No', N'No', N'54200|54300', 69)
GO
INSERT [dbo].[balance] ([Nº fila], [Descripción], [Tipo sumatorio], [Sumatorio], [Tipo], [Muestra signo opuesto], [Sólo positivo], [Cambia signo], [Código Areas Totales], [Código Proveedores Totales], [Total dimensión 3], [Total dimensión 4], [Muestra], [Negrita], [Itálica], [Subrayar], [Muestra signo opuesto2], [Cambiar página], [Sumatorio char], [ID]) VALUES (N'B05&gt;03', N'Valores representativos de deuda', N'Cuentas mayor', NULL, N'Activo', N'No', N'No', N'No', NULL, NULL, NULL, NULL, N'Sí', N'No', N'No', N'No', N'No', N'No', N'54100|54600|59700', 70)
GO
INSERT [dbo].[balance] ([Nº fila], [Descripción], [Tipo sumatorio], [Sumatorio], [Tipo], [Muestra signo opuesto], [Sólo positivo], [Cambia signo], [Código Areas Totales], [Código Proveedores Totales], [Total dimensión 3], [Total dimensión 4], [Muestra], [Negrita], [Itálica], [Subrayar], [Muestra signo opuesto2], [Cambiar página], [Sumatorio char], [ID]) VALUES (N'B05&gt;04', N'Derivados', N'Cuentas mayor', NULL, N'Activo', N'No', N'No', N'No', NULL, NULL, NULL, NULL, N'Sí', N'No', N'No', N'No', N'No', N'No', N'', 71)
GO
INSERT [dbo].[balance] ([Nº fila], [Descripción], [Tipo sumatorio], [Sumatorio], [Tipo], [Muestra signo opuesto], [Sólo positivo], [Cambia signo], [Código Areas Totales], [Código Proveedores Totales], [Total dimensión 3], [Total dimensión 4], [Muestra], [Negrita], [Itálica], [Subrayar], [Muestra signo opuesto2], [Cambiar página], [Sumatorio char], [ID]) VALUES (N'B05&gt;05', N'Otros activos financieros', N'Cuentas mayor', NULL, N'Activo', N'No', N'No', N'No', NULL, NULL, NULL, NULL, N'Sí', N'No', N'No', N'No', N'No', N'No', N'54500|54800|56500|56600', 72)
GO
INSERT [dbo].[balance] ([Nº fila], [Descripción], [Tipo sumatorio], [Sumatorio], [Tipo], [Muestra signo opuesto], [Sólo positivo], [Cambia signo], [Código Areas Totales], [Código Proveedores Totales], [Total dimensión 3], [Total dimensión 4], [Muestra], [Negrita], [Itálica], [Subrayar], [Muestra signo opuesto2], [Cambiar página], [Sumatorio char], [ID]) VALUES (N'B05&gt;06', N'Otras inversiones', N'Cuentas mayor', NULL, N'Activo', N'No', N'No', N'No', NULL, NULL, NULL, NULL, N'Sí', N'No', N'No', N'No', N'No', N'No', N'', 73)
GO
INSERT [dbo].[balance] ([Nº fila], [Descripción], [Tipo sumatorio], [Sumatorio], [Tipo], [Muestra signo opuesto], [Sólo positivo], [Cambia signo], [Código Areas Totales], [Código Proveedores Totales], [Total dimensión 3], [Total dimensión 4], [Muestra], [Negrita], [Itálica], [Subrayar], [Muestra signo opuesto2], [Cambiar página], [Sumatorio char], [ID]) VALUES (N'B05', N'INVERSIONES FINANCIERAS A CORTO PLAZO', N'Fórmula', NULL, N'Activo', N'No', N'No', N'No', NULL, NULL, NULL, NULL, N'Sí', N'Sí', N'No', N'No', N'No', N'No', N'B05&gt;01+B05&gt;02+B05&gt;03+B05&gt;04+B05&gt;05+B05&gt;06', 74)
GO
INSERT [dbo].[balance] ([Nº fila], [Descripción], [Tipo sumatorio], [Sumatorio], [Tipo], [Muestra signo opuesto], [Sólo positivo], [Cambia signo], [Código Areas Totales], [Código Proveedores Totales], [Total dimensión 3], [Total dimensión 4], [Muestra], [Negrita], [Itálica], [Subrayar], [Muestra signo opuesto2], [Cambiar página], [Sumatorio char], [ID]) VALUES (N'B06', N'PERIODIFICACIONES A CORTO PLAZO', N'Cuentas mayor', NULL, N'Activo', N'No', N'No', N'No', NULL, NULL, NULL, NULL, N'Sí', N'Sí', N'No', N'No', N'No', N'No', N'41700|48000', 75)
GO
INSERT [dbo].[balance] ([Nº fila], [Descripción], [Tipo sumatorio], [Sumatorio], [Tipo], [Muestra signo opuesto], [Sólo positivo], [Cambia signo], [Código Areas Totales], [Código Proveedores Totales], [Total dimensión 3], [Total dimensión 4], [Muestra], [Negrita], [Itálica], [Subrayar], [Muestra signo opuesto2], [Cambiar página], [Sumatorio char], [ID]) VALUES (N'B07&gt;01', N'Tesorería', N'Cuentas mayor', NULL, N'Activo', N'No', N'No', N'No', NULL, NULL, NULL, NULL, N'Sí', N'No', N'No', N'No', N'No', N'No', N'57000|57100|57200|57209|57300|57309', 76)
GO
INSERT [dbo].[balance] ([Nº fila], [Descripción], [Tipo sumatorio], [Sumatorio], [Tipo], [Muestra signo opuesto], [Sólo positivo], [Cambia signo], [Código Areas Totales], [Código Proveedores Totales], [Total dimensión 3], [Total dimensión 4], [Muestra], [Negrita], [Itálica], [Subrayar], [Muestra signo opuesto2], [Cambiar página], [Sumatorio char], [ID]) VALUES (N'B07&gt;02', N'Otros activos líquidos equivalentes', N'Cuentas mayor', NULL, N'Activo', N'No', N'No', N'No', NULL, NULL, NULL, NULL, N'Sí', N'No', N'No', N'No', N'No', N'No', N'', 77)
GO
INSERT [dbo].[balance] ([Nº fila], [Descripción], [Tipo sumatorio], [Sumatorio], [Tipo], [Muestra signo opuesto], [Sólo positivo], [Cambia signo], [Código Areas Totales], [Código Proveedores Totales], [Total dimensión 3], [Total dimensión 4], [Muestra], [Negrita], [Itálica], [Subrayar], [Muestra signo opuesto2], [Cambiar página], [Sumatorio char], [ID]) VALUES (N'B07', N'EFECTIVO Y OTROS ACTIVOS LÍQUIDOS EQUIV.', N'Fórmula', NULL, N'Activo', N'No', N'No', N'No', NULL, NULL, NULL, NULL, N'Sí', N'Sí', N'No', N'No', N'No', N'No', N'B07&gt;01+B07&gt;02', 78)
GO
INSERT [dbo].[balance] ([Nº fila], [Descripción], [Tipo sumatorio], [Sumatorio], [Tipo], [Muestra signo opuesto], [Sólo positivo], [Cambia signo], [Código Areas Totales], [Código Proveedores Totales], [Total dimensión 3], [Total dimensión 4], [Muestra], [Negrita], [Itálica], [Subrayar], [Muestra signo opuesto2], [Cambiar página], [Sumatorio char], [ID]) VALUES (N'B', N'ACTIVO CORRIENTE', N'Fórmula', NULL, N'Activo', N'No', N'No', N'No', NULL, NULL, NULL, NULL, N'Sí', N'Sí', N'No', N'No', N'No', N'No', N'B01+B02+B03+B04+B05+B06+B07', 79)
GO
INSERT [dbo].[balance] ([Nº fila], [Descripción], [Tipo sumatorio], [Sumatorio], [Tipo], [Muestra signo opuesto], [Sólo positivo], [Cambia signo], [Código Areas Totales], [Código Proveedores Totales], [Total dimensión 3], [Total dimensión 4], [Muestra], [Negrita], [Itálica], [Subrayar], [Muestra signo opuesto2], [Cambiar página], [Sumatorio char], [ID]) VALUES (N'A+B', N'TOTAL ACTIVO', N'Fórmula', NULL, N'Activo', N'No', N'No', N'No', NULL, NULL, NULL, NULL, N'Sí', N'Sí', N'No', N'No', N'No', N'No', N'A+B', 80)
GO
INSERT [dbo].[balance] ([Nº fila], [Descripción], [Tipo sumatorio], [Sumatorio], [Tipo], [Muestra signo opuesto], [Sólo positivo], [Cambia signo], [Código Areas Totales], [Código Proveedores Totales], [Total dimensión 3], [Total dimensión 4], [Muestra], [Negrita], [Itálica], [Subrayar], [Muestra signo opuesto2], [Cambiar página], [Sumatorio char], [ID]) VALUES (N'F01&gt;01&gt;01', N'Capital escriturado', N'Cuentas mayor', 10000, N'Pasivo', N'No', N'No', N'No', NULL, NULL, NULL, NULL, N'Sí', N'No', N'Sí', N'No', N'No', N'No', N'10000', 81)
GO
INSERT [dbo].[balance] ([Nº fila], [Descripción], [Tipo sumatorio], [Sumatorio], [Tipo], [Muestra signo opuesto], [Sólo positivo], [Cambia signo], [Código Areas Totales], [Código Proveedores Totales], [Total dimensión 3], [Total dimensión 4], [Muestra], [Negrita], [Itálica], [Subrayar], [Muestra signo opuesto2], [Cambiar página], [Sumatorio char], [ID]) VALUES (N'F01&gt;01&gt;02', N'(Capital no exigido)', N'Cuentas mayor', 10300, N'Pasivo', N'No', N'No', N'No', NULL, NULL, NULL, NULL, N'Sí', N'No', N'Sí', N'No', N'No', N'No', N'10300', 82)
SET IDENTITY_INSERT [dbo].[balance] OFF
GO

Una vez que tenemos creadas nuestras tablas de ejemplo, tenemos que ver la forma de sincronizar ambas tablas. Hay muchos factores, de hecho no estoy seguro de que en este script los contemple todos, pero espero que si la mayoría :).

Lo primero que vamos a hacer es determinar si la tabla tiene una columna identidad, si es así para insertar datos hay que ejecutar primero el set identity_insert on de la tabla en cuestión. Vamos a crear un script que haga cada una de las partes necesarias. El primer trozo comprobará si hay o no valor de identidad.

DECLARE @SQL NVARCHAR(MAX)

declare @tabla varchar(100)

set @tabla=‘Balance’

select @SQL=;Seg

if (exists(select 1 from sys.columns where is_identity=1 and object_id=OBJECT_ID(‘dbo.’+@tabla)))

Select @SQL=N’SET IDENTITY_INSERT demo.dbo.’+@tabla+‘ ON;’;

Despues lo que haremos será generar el comando merge que inserte los datos.

SET @SQL =@SQL+ N’MERGE into demo.dbo.’ +@tabla +‘ Destination using (select * from dbo.’+@tabla +‘ ) as Source ON ‘

despues hay que averiguar cual es la clave primaria de la tabla (no podriamos hacer esto si no la tuviera).

La clave primaria de la tabla está entre tres tablas, sys.indexes, sys.index_columns, y sys.columns, tenemos que sacar todas las columnas y quedarnos con la condición.

Esta es la forma.
SET @SQL=@SQL + STUFF( (

SELECT ‘AND ‘ + ‘Destination.’++QUOTENAME(col.name)+‘ = Source.’ +QUOTENAME(COL.name) FROM SYS.indexes i

inner join SYS.index_columns c

inner join sys.columns col on c.object_id=col.object_id and c.column_id=col.column_id

on i.object_id=c.object_id and i.is_primary_key=1

WHERE i.object_id=OBJECT_ID(‘dbo.’+@tabla)

FOR XML PATH()),1,4,)

 

s las ocnvertiraa en una sola. Empezará de esta forma, “and Destination.columna=Source.columna and …” de forma que con la instrucción stuff quitamos los 4 primeros caracteres y listo.

Ahora hay que hacer el comando insert,

SELECT @SQL=@sql + ‘ WHEN NOT MATCHED THEN INSERT (‘

+ STUFF( (select ‘,’+ QUOTENAME(col.name)

from SYS.COLUMNS col

LEFT JOIN sys.index_columns ic

inner join sys.indexes i

on ic.object_id=i.object_id and ic.index_id=i.index_id and i.is_primary_key=1

on col.object_id=ic.object_id and col.column_id=ic.column_id

WHERE is_computed=0 and col.object_id=OBJECT_ID(‘dbo.’+@tabla)

FOR XML PATH()

),1,1,)

 

hay que poner la lista de columnas separadas por comas,  como podemos ver es la misma forma de actuar que en la parte anterior.

+‘) VALUES (‘+

stuff( (

select ‘, Source.’+quotename(col.name)

from SYS.COLUMNS col

LEFT JOIN sys.index_columns ic

inner join sys.indexes i

on ic.object_id=i.object_id and ic.index_id=i.index_id and i.is_primary_key=1

on col.object_id=ic.object_id and col.column_id=ic.column_id

WHERE is_computed=0 and col.object_id=OBJECT_ID(‘dbo.’+@tabla)

for xml path()

),1,1,)+‘)’

 

Y ahora los valores, que son las columnas de la tabla Source,

De esta forma ya tenemos construidos los INSERTS, Ahora vamos con las actualizaciones, la idea es la misma, solo hemos de tener en cuenta no actualizar la pk.

select @SQL=@sql +‘ WHEN MATCHED THEN UPDATE SET ‘+

stuff( (

select ‘, Destination.’ +quotename(col.name)

+‘ = Source.’+quotename(col.name)

from SYS.COLUMNS col

LEFT JOIN sys.index_columns ic

inner join sys.indexes i

on ic.object_id=i.object_id and ic.index_id=i.index_id

on col.object_id=ic.object_id and col.column_id=ic.column_id

WHERE is_computed=0 and col.object_id=OBJECT_ID(‘dbo.’+@tabla) and i.is_primary_key is null

for xml path()

),1,1,)+‘;’

 

Finalizamos poniendo el set identity_insert off

if (exists(select 1 from sys.columns where is_identity=1 and object_id=OBJECT_ID(‘dbo.’+@tabla)))

set @SQL=@SQL+N’SET IDENTITY_INSERT demo.dbo.’+@tabla+‘ Off;’;

 

 

 

El script completo puede verse aquí

 

DECLARE @SQL NVARCHAR(MAX)
declare @tabla varchar(100)
set @tabla='Balance'
select @SQL='';
 
 
 
 
if (exists(select 1 from sys.columns where is_identity=1 and object_id=OBJECT_ID('dbo.'+@tabla)))
 Select @SQL=N'SET IDENTITY_INSERT demo.dbo.'+@tabla+' ON;';
 
SET @SQL =@SQL+ N'MERGE into demo.dbo.' +@tabla +' Destination using (select * from dbo.'+@tabla +' ) as Source ON '
 
SET @SQL=@SQL + STUFF( (
SELECT 'AND ' + 'Destination.'++QUOTENAME(col.name)+' = Source.' +QUOTENAME(COL.name)  FROM SYS.indexes i 
         inner join SYS.index_columns  c
				inner join sys.columns col on c.object_id=col.object_id and c.column_id=col.column_id
		    on i.object_id=c.object_id and i.is_primary_key=1
WHERE i.object_id=OBJECT_ID('dbo.'+@tabla) 
FOR XML PATH('')),1,4,'')
SELECT @SQL=@sql + ' WHEN NOT MATCHED THEN  INSERT (' 
+ STUFF( (select ','+ QUOTENAME(col.name)
from SYS.COLUMNS col
    LEFT JOIN sys.index_columns ic 
				inner join sys.indexes i
				on ic.object_id=i.object_id and ic.index_id=i.index_id and i.is_primary_key=1
	on col.object_id=ic.object_id and col.column_id=ic.column_id 
 WHERE is_computed=0 and col.object_id=OBJECT_ID('dbo.'+@tabla)
 FOR XML PATH('')
 ),1,1,'')
 
  +') VALUES ('+
 stuff( (
	select ', Source.'+quotename(col.name) 
	from SYS.COLUMNS col
    LEFT JOIN sys.index_columns ic 
				inner join sys.indexes i
				on ic.object_id=i.object_id and ic.index_id=i.index_id and i.is_primary_key=1
	on col.object_id=ic.object_id and col.column_id=ic.column_id 
	WHERE is_computed=0 and col.object_id=OBJECT_ID('dbo.'+@tabla)
	for xml path('')
	),1,1,'')+')'
 
select @SQL=@sql +' WHEN MATCHED THEN  UPDATE SET '+
stuff( (
	select ', Destination.' +quotename(col.name) 
 +' = Source.'+quotename(col.name) 
	from SYS.COLUMNS col
    LEFT JOIN sys.index_columns ic 
				inner join sys.indexes i
				on ic.object_id=i.object_id and ic.index_id=i.index_id 
	on col.object_id=ic.object_id and col.column_id=ic.column_id 
	WHERE is_computed=0 and col.object_id=OBJECT_ID('dbo.'+@tabla) and i.is_primary_key is null
	for xml path('')
	),1,1,'')+';'
 
	if (exists(select 1 from sys.columns where is_identity=1 and object_id=OBJECT_ID('dbo.'+@tabla)))
 set @SQL=@SQL+N'SET IDENTITY_INSERT demo.dbo.'+@tabla+' Off;';
 
 select @SQL
exec sp_executesql @SQL,N''