Problemas con connect by prior

Tengo un problema al usar en una sentencia connect by prior y es que la recursividad puede ser infinita, sabes de alguna manera de controlar dicha situación
Otro pequeño problema si se producen referencias cíclicas, es decir un hijo puede ser padre de si mismo se produce un error, ¿esto tiene solución?

1 Respuesta

Respuesta
1
Por lo que me estás indicando, todo tiene la apariencia de intentar consultar información aparentemente de árbol jerarquizado, pero que en algunas de sus ramas aparecen los que llamado en 'C' listas circulares.
En principio los operadores de 'Start with ... Connect by prior ...' están diseñados para arboles perfectamente jerárquicos donde la recusividad no ha de ser infinita (listas circulares ni reflexivas. Ni en el otro caso de asociación recursiva (uno es padre de si mismo!).
De todas formas me tendrías que haber indicado la version de Oracle con la que estás trabajando.
En la excepción de 'REFLEXIVIDAD' (un elemento es padre de si mismo) es muy fácil de solucionar, simplemente indicando en la clausula del predicado :
WHERE Columna_Padre != Columna_Hijo que son las dos que utilizar en el 'connect by prior ...' para establecer la relación.
Luego si quieres que aparezcan como resultado, simplemente tienes que añadir a tu consulta una 'UNION' o mejor un 'UNION ALL' si los datos que devuelves en la consulta nunca se duplicaran en ambas consultas (ya que el rendimiento es mejor).
Select_con_connect_by_prior
UNION ALL
Select columnas
from tablas
where columna_padre = columna_hijo;
Respecto al tema de 'listas circulares' el problema puede ser mucho más complejo. Pero vamos a ver si lo podemos solventar de alguna de las formas que explico a continuación :
En la versión 11g de Oracle cuentas con la solución a las listas cíclicas, identificando en la propia condición que si se trata de una lista cíclica, no se repita. La forma es utilizando :
Select ...
from ...
Where ...
Start with ...
Connect by NOCYCLE prior padre = hijo
El 'CONNECT BY NOCYCLE PRIOR ...' te salva de estas situaciones!
Supongo que te saldrá cuando lo utilizas ahora en listas circulares un error : ORA-01436 con un texto más o menos como este : 'CONNECT BY loop in teh user data'.
Pero esta OPCIÓN sólo está habilitada a partir de la 10g en adelante, por eso el preguntarte que debías de haberme indicado la version con la que estás trabajando.
Pero si estás en otra versión ...
1.- Si la relación es entre columnas numéricas entre padres e hijos y los hijos siempre tendrán un número inferior al de sus padres (muchas cohincidencias ...) entonces con añadir a tu sentencia en el 'WHERE' que 'columna_padre < columna hijo' podria ser una solución.
2.- Otra solución es trabajar con el valor de la pseudo-columna LEVEL.
Puedes poner que el nivel no supere a un determinado valor colocando :
Select distinct .... connect by prior padre = hijo and LEVEL < 20;
El condicionante de esta solución es que el árbol no tenga más de 20 ramas, y que ninguna relación de las columnas especificada se repita (y no incluir level en la lista de columnas a recuperar).
:-(
Por último, la única forma de realizarlo es mediante la creación de una función que analice 'tokems' y controlarlo emulando el CONNECT BY PRIOR.
;-(
Si quieres ves haciendo la prueba. Indicame si trabajas con alguna versión de Oracle inferior a la 10g, para intentar emular y solventar esta situación de alguna forma ...
Mientras espero tu respuesta, un cordial saludo
Ramón
NOTA : Veo que eres de España! Si tienes contacto con empresas de Barcelona que requieran de los servicios de alguien con mi perfil, te estaría muy agradecida que me lo comunicases.
Ya que busco trabajo.
Lo haríamos por una respuesta en privado.
GRACIAS Y DIME ALGO (sobre lo relativo a tu pregunta), ¿OK?
Una respuesta excelente. Estoy trabajando con la version 9 pero se esta planteando la posibilidad de pasar dentro de poco a la version 10.
Gracias

Añade tu respuesta

Haz clic para o

Más respuestas relacionadas