La descarga está en progreso. Por favor, espere

La descarga está en progreso. Por favor, espere

Leonel Morales Díaz Ingeniería Simple

Presentaciones similares


Presentación del tema: "Leonel Morales Díaz Ingeniería Simple"— Transcripción de la presentación:

1 Leonel Morales Díaz Ingeniería Simple leonel@ingenieriasimple.com
Tablas y Funciones de SQL Server para Implementar una Jerarquía sin Límite de Niveles Leonel Morales Díaz Ingeniería Simple Copyright 2008 by Leonel Morales Díaz – Ingeniería Simple. Derechos reservados Disponible en:

2 Jerarquías usuales Estructura tabla padre – tabla hijo
La llave primaria de la padre es llave foránea en la hija Puede haber una tabla nieto Hasta una biznieto Padres Código Descripción Hijos Código CódigoPadre Descripción Nietos Código CódigoHijoPadre Descripción

3 Problemas en jerarquías
Limitada a tres niveles O a la cantidad de niveles establecida Inflexibilidad: Nuevos niveles reales deben ser “adaptados” La estructura es permanente y coercitiva Aunque un nivel ya no sea necesario Dificultad de consultas Se trata de relacionar tres o más tablas

4 Jerarquías de una sola tabla
Estructura registro hijo – registro padre La llave primaria es llave foránea de la misma tabla Si no hay padre la llave foránea es nula Tabla con relación a sí misma Datos Código CódigoPadre Descripción

5 Ventajas jerarquía unitabla
Ilimitados niveles Se ajusta a las necesidades reales Consultas más sencillas Estructura más simple Llega a conocerse muy bien Bastante flexible

6 Desventajas El nivel del registro no se conoce inmediatamente
En la jerarquía tradicional se conoce el nivel con solo saber a qué tabla pertenece Se necesita agregar campos para esto

7 Jerarquía contable Usualmente por posiciones en una cadena
#.##.###.#### Cuenta, subcuenta, sub-subcuenta, cuenta de detalle, etc. Puede ser una sola tabla Con referencia a sí misma La cantidad de niveles está pre-establecida No hay necesidad de campo con cuenta padre Usualmente se llama Nomenclatura Contable

8 Ejemplo jerarquía contable
En el código está implícito el código del padre Puede ser necesario poner validaciones para evitar que se inserte un código sin padre Los códigos de longitud 1 no tienen padre Una sola tabla Código Cuenta 1 Activo 2 Pasivo 3 Capital 4 Gastos 5 Ingresos 1.1 Circulante 1.2 Fijo 1.3 Diferido 2.1 Circulante 2.2 Fijo 2.3 Diferido 3.1 Acciones al portador 3.2 Acciones preferentes 4.1 Fijos 4.2 Variables 5.1 Fijos 5.2 Variables 1.1.1 Caja 1.1.2 Bancos

9 Nomenclatura Implementación
Puede hacerse mediante “constraints” de tipo “Check” Y una función para encontrar el código padre Si la función devuelve “Null” no se acepta CREATE TABLE Nomenclatura( Código nVarChar(13) NOT NULL CONSTRAINT Código_Nomenclatura Check ( (Código Like '[1-9]' Or Código Like '[1-9].[0-9][0-9]' Or Código Like '[1-9].[0-9][0-9].[0-9][0-9][0-9]' Or Código Like '[1-9].[0-9][0-9].[0-9][0-9][0-9].[0-9][0-9][0-9][0-9]') And (len(Código)=1 Or Not dbo.CuentaPadre(Código) Is Null)), Cuenta nVarChar(30) NULL, Constraint PK_Nomenclatura Primary Key Clustered ( Código ASC ) ) Nomenclatura Código Cuenta

10 Función para chequeo CuentaPadre(@Código)
Encuentra la cuenta padre Si no hay devuelve “Null” CREATE FUNCTION CuentaPadre nVarChar(13) ) RETURNS nVarChar(13) AS BEGIN nVarChar(13) = Null If > 0 Begin nVarChar(13) = While <> '.' = = Código From Nomenclatura Where Código End END

11 Padre y nivel Se pueden implementar con campos calculados Padre Nivel
El valor devuelto por CuentaPadre Nivel El número de puntos más 1 Se puede hacer con una función que los cuente o aprovechando la función Like

12 Tabla con padre y nivel Nomenclatura Código Cuenta Padre Nivel
CREATE TABLE Nomenclatura( Código nVarChar(13) NOT NULL CONSTRAINT Código_Nomenclatura Check ( (Código Like '[1-9]' Or Código Like '[1-9].[0-9][0-9]' Or Código Like '[1-9].[0-9][0-9].[0-9][0-9][0-9]' Or Código Like '[1-9].[0-9][0-9].[0-9][0-9][0-9].[0-9][0-9][0-9][0-9]') And (len(Código)=1 Or Not dbo.CuentaPadre(Código) Is Null)), Cuenta nVarChar(30) NULL, Padre As dbo.CuentaPadre(Código), Nivel As Case When Código Like '%.%.%.%' Then 4 When Código Like '%.%.%' Then 3 When Código Like '%.%' Then 2 Else 1 End, Constraint PK_Nomenclatura Primary Key Clustered ( Código ASC ) ) Nomenclatura Código Cuenta Padre Nivel

13 Datos de tabla Nomenclatura
Select * From Nomenclatura Código Cuenta Padre Nivel Activo NULL Circulante Caja Bancos Banco Industrial Banco Continental Banco Internacional Fijo Diferido Pasivo NULL Circulante Fijo Diferido Capital NULL Acciones al portador Acciones preferentes Gastos NULL Fijos Variables Ingresos NULL Fijos Variables (22 row(s) affected)

14 Otros tipos de jerarquía
Por ruta o “path” Similar a la de directorios de windows Se tiene un nodo “raíz” y un separador C:, D:, etc., son raíces \ es el separador Todos los nodos de un mismo nivel tienen la misma cantidad de separadores en la ruta Todos los hijos de un mismo nodo comparten el mismo prefijo Generalización: jerarquía por prefijo Puede o no existir separador En cualquier caso se usa solo una tabla

15 Planteamiento Partiendo de una jerarquía de una sola tabla construir las consultas para: Obtener la lista de padres Registros sin padre Obtener la lista de registros en el nivel “n” Obtener la lista de registros descendientes del registro “R” Obtener la lista de registros que descienden del registro “P” y están en el nivel “m”

16 Tabla básica Solo tres campos El resto serán calculados Código
CódigoPadre Descripción El resto serán calculados Padre Nivel Ruta Datos Código CódigoPadre Descripción

17 Creación de la tabla básica
La tabla permite almacenar cualquier jerarquía En este ejemplo se usará para países y provincias geográficas (departamentos), municipios, etc. CREATE TABLE Datos( Código Int NOT NULL, CódigoPadre Int NULL Constraint FK_Datos_CódigoPadre Foreign Key References Datos ( Código ), Descripción nVarChar(Max), Constraint PK_Datos Primary Key Clustered ( Código ASC ) ) Datos Código CódigoPadre Descripción

18 Registros para pruebas
Select * From Datos Código CódigoPadre Descripción NULL Guatemala NULL El Salvador NULL Honduras NULL Nicaragua NULL Costa Rica NULL Belice NULL Panamá Guatemala Sacatepequez Chimaltenango Sololá Totonicapán Huehuetenango Quetzaltenango San Marcos Retalhuleu Suchitepequez Escuintla Santa Rosa Jutiapa Jalapa Zacapa Izabal Baja Verapaz Alta Verapaz Quiché Petén El Progreso Ciudad de Guatemala Mixco Villa Nueva Jocotenango San Juan Sacatepequez San Raymundo Antigua Guatemala Amatitlán Atitlán San Pedro La Laguna Chiantla Los Regadillos Huehuetenango El Terrero El Cambote (43 row(s) affected)

19 Lista de padres Padres: Registros sin padre CódigoPadre Is Null
Select * From Datos Where CódigoPadre Is Null Código CódigoPadre Descripción NULL Guatemala NULL El Salvador NULL Honduras NULL Nicaragua NULL Costa Rica NULL Belice NULL Panamá (7 row(s) affected)

20 Lista de registros en nivel “n”
Se necesita una función que calcule el nivel Puede ser recursiva Select * From Datos Where dbo.CalculaNivelDato(Código) = 3 Código CódigoPadre Descripción Ciudad de Guatemala Mixco Villa Nueva Jocotenango San Juan Sacatepequez San Raymundo Antigua Guatemala Amatitlán Atitlán San Pedro La Laguna Chiantla Huehuetenango (12 row(s) affected) Create Function CalculaNivelDato As Int ) Returns Int As Begin Int Int = CódigoPadre From Datos Where Código If Is Null = 1 Else = + 1 End

21 Nivel como campo calculado
Se puede incorporar el nivel como campo calculado Usando la función CalculaNivelDato Select * From Datos Where Nivel = 3 or Nivel = 4 Código CódigoPadre Descripción Nivel Ciudad de Guatemala 3 Mixco Villa Nueva Jocotenango San Juan Sacatepequez 3 San Raymundo Antigua Guatemala Amatitlán Atitlán San Pedro La Laguna 3 Chiantla Los Regadillos Huehuetenango El Terrero El Cambote (15 row(s) affected) CREATE TABLE Datos( Código Int NOT NULL, CódigoPadre Int NULL Constraint FK_Datos_CódigoPadre Foreign Key References Datos ( Código ), Descripción nVarChar(Max), Nivel As dbo.CalculaNivelDato(Código), Constraint PK_Datos Primary Key Clustered ( Código ASC ) )

22 Lista de descendientes de “R”
Prerrequisito: Función que construye el “path” hacía la raíz También se puede hacer recursiva Usa delimitadores: “>” antes y “=“ después Para evitar el código 30 se confunda con el 3030 por ejemplo Facilita las búsquedas Ejemplo: path de 30: >1=>8=>30=

23 Función de ruta Select Código, dbo.ComponePathDato(Código) From Datos
Where Nivel = 3 or Nivel = 4 Código >1=>8=>29= >1=>8=>30= >1=>8=>31= >1=>8=>32= >1=>9=>33= >1=>9=>34= >1=>9=>35= >1=>8=>36= >1=>11=>37= >1=>11=>38= >1=>13=>39= >1=>13=>39=>40= >1=>13=>41= >1=>13=>41=>42= >1=>13=>41=>43= (15 row(s) affected) Create Function ComponePathDato As Int ) Returns nVarChar(Max) As Begin Int nVarChar(Max) = '>' + + '=' = CódigoPadre From Datos Where Código If Not Is Null = End

24 Ruta como campo calculado
Similar al caso de Nivel CREATE TABLE Datos( Código Int NOT NULL, CódigoPadre Int NULL Constraint FK_Datos_CódigoPadre Foreign Key References Datos ( Código ), Descripción nVarChar(Max), Nivel As dbo.CalculaNivelDato(Código), Ruta As dbo.ComponePathDato(Código), Constraint PK_Datos Primary Key Clustered ( Código ASC ) ) Select Código, Nivel, Ruta From Datos Where Nivel = 4 Código Nivel Ruta >1=>13=>39=>40= >1=>13=>41=>42= >1=>13=>41=>43= (3 row(s) affected)

25 ¡Ahora sí! Descendientes de “R”
Descendientes de “R” tienen la ruta de “R” en su ruta nVarChar(Max) = Ruta From Datos Where Código = 13 Select * From Datos Where Ruta + '%' And Ruta Código CódigoPadre Descripción Nivel Ruta Chiantla >1=>13=>39= Los Regadillos >1=>13=>39=>40= Huehuetenango >1=>13=>41= El Terrero >1=>13=>41=>42= El Cambote >1=>13=>41=>43= (5 row(s) affected)

26 Descendientes de “P” en nivel “m”
Igual que el anterior Pero con condición sobre el nivel nVarChar(Max) = Ruta From Datos Where Código = 13 Select * From Datos Where Ruta + '%' And Ruta And Nivel = 3 Código CódigoPadre Descripción Nivel Ruta Chiantla >1=>13=>39= Huehuetenango >1=>13=>41= (2 row(s) affected) Select * From Datos Where Ruta + '%' And Ruta And Nivel = 4 Código CódigoPadre Descripción Nivel Ruta Los Regadillos >1=>13=>39=>40= El Terrero >1=>13=>41=>42= El Cambote >1=>13=>41=>43= (3 row(s) affected)

27 Variaciones de las funciones
Calcular el nivel a partir de la ruta El nivel es el número de “>” o “=“ en la ruta Transformar las funciones a formas no recursivas Usar vistas para evitar los campos calculados Poner el código en “Identity” generado automáticamente

28 Formas no recursivas Función de cálculo de nivel
Create Function CalculaNivelDato As Int ) Returns Int As Begin Int = CódigoPadre From Datos Where Código Int = 1 While Is Null Begin + 1 = CódigoPadre From Datos Where Código End

29 Formas no recursivas Función de composición de rutas
Create Function ComponePathDato As Int ) Returns nVarChar(Max) As Begin Int nVarChar(Max) = CódigoPadre, @Path = '>' + Convert(nVarChar(Max),Código) + '=' From Datos Where Código While Is Null @Path = '>' + Convert(nVarChar(Max),Código) + '=' From Datos Where Código End


Descargar ppt "Leonel Morales Díaz Ingeniería Simple"

Presentaciones similares


Anuncios Google