La descarga está en progreso. Por favor, espere

La descarga está en progreso. Por favor, espere

Tablas y Funciones de SQL Server para Implementar una Jerarquía sin Límite de Niveles Leonel Morales Díaz Ingeniería Simple

Presentaciones similares


Presentación del tema: "Tablas y Funciones de SQL Server para Implementar una Jerarquía sin Límite de Niveles Leonel Morales Díaz Ingeniería Simple"— Transcripción de la presentación:

1 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ódigoCuenta 1Activo 2Pasivo 3Capital 4Gastos 5Ingresos 1.1Circulante 1.2Fijo 1.3Diferido 2.1Circulante 2.2Fijo 2.3Diferido 3.1Acciones al portador 3.2Acciones preferentes 4.1Fijos 4.2Variables 5.1Fijos 5.2Variables 1.1.1Caja 1.1.2Bancos

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 Nomenclatura Código Cuenta 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 ) )

10 Función para chequeo –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 –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 ) )

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 5 2 (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 –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 2 NULL El Salvador 3 NULL Honduras 4 NULL Nicaragua 5 NULL Costa Rica 6 NULL Belice 7 NULL Panamá 8 1 Guatemala 9 1 Sacatepequez 10 1 Chimaltenango 11 1 Sololá 12 1 Totonicapán 13 1 Huehuetenango 14 1 Quetzaltenango 15 1 San Marcos 16 1 Retalhuleu 17 1 Suchitepequez 18 1 Escuintla 19 1 Santa Rosa 20 1 Jutiapa 21 1 Jalapa 22 1 Zacapa 23 1 Izabal 24 1 Baja Verapaz 25 1 Alta Verapaz 26 1 Quiché 27 1 Petén 28 1 El Progreso 29 8 Ciudad de Guatemala 30 8 Mixco 31 8 Villa Nueva 32 8 Jocotenango 33 9 San Juan Sacatepequez 34 9 San Raymundo 35 9 Antigua Guatemala 36 8 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 2 NULL El Salvador 3 NULL Honduras 4 NULL Nicaragua 5 NULL Costa Rica 6 NULL Belice 7 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 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 Select * From Datos Where dbo.CalculaNivelDato(Código) = 3 Código CódigoPadre Descripción Ciudad de Guatemala 30 8 Mixco 31 8 Villa Nueva 32 8 Jocotenango 33 9 San Juan Sacatepequez 34 9 San Raymundo 35 9 Antigua Guatemala 36 8 Amatitlán Atitlán San Pedro La Laguna Chiantla Huehuetenango (12 row(s) affected)

21 Nivel como campo calculado Se puede incorporar el nivel como campo calculado –Usando la función CalculaNivelDato 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 ) ) Select * From Datos Where Nivel = 3 or Nivel = 4 Código CódigoPadre Descripción Nivel 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 4 (15 row(s) affected)

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 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 Select Código, dbo.ComponePathDato(Código) From Datos Where Nivel = 3 or Nivel = 4 Código >1=>8=>29= 30 >1=>8=>30= 31 >1=>8=>31= 32 >1=>8=>32= 33 >1=>9=>33= 34 >1=>9=>34= 35 >1=>9=>35= 36 >1=>8=>36= 37 >1=>11=>37= 38 >1=>11=>38= 39 >1=>13=>39= 40 >1=>13=>39=>40= 41 >1=>13=>41= 42 >1=>13=>41=>42= 43 >1=>13=>41=>43= (15 row(s) affected)

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= 42 4 >1=>13=>41=>42= 43 4 >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 3 >1=>13=>39= Los Regadillos 4 >1=>13=>39=>40= Huehuetenango 3 >1=>13=>41= El Terrero 4 >1=>13=>41=>42= El Cambote 4 >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 3 >1=>13=>39= Huehuetenango 3 >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 4 >1=>13=>39=>40= El Terrero 4 >1=>13=>41=>42= El Cambote 4 >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 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) = = '>' + Convert(nVarChar(Max),Código) + '=' From Datos Where Código While Is Null = = '>' + Convert(nVarChar(Max),Código) + '=' From Datos Where Código End


Descargar ppt "Tablas y Funciones de SQL Server para Implementar una Jerarquía sin Límite de Niveles Leonel Morales Díaz Ingeniería Simple"

Presentaciones similares


Anuncios Google