08/07/2008, 00:38
|
| | | Fecha de Ingreso: abril-2004
Mensajes: 84
Antigüedad: 20 años, 7 meses Puntos: 0 | |
Respuesta: select recursivo Pues la verdad que hace tiempo que no no toco esa cnsulta ya que lleve tiempo funcionando bien. Pero he encntrado una respuesta en otro foro que creo que te será muy util.
Código:
Hola,
Por lo que me estás indicando, todo tiene la apariencia de intentar consultar información aparentemente de arbol 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 ...' estan diseñados para arboles perfectamente jerarquicos 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 excepcion de 'REFLEXIVIDAD' (un elemento es padre de si mismo) es muy facil 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 ciclicas, identificando en la propia condición que si se trata de una lista ciclica, 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 OPCION sólo está habilitada a partir de la 10g en adelante, por eso el preguntarte que debias de haberme indicado la version con la que estás trabajando.
Pero si estás en otra versión ...
1.- Si la relacion es entre columnas numericas entre padres e hijos y los hijos siempre tendran 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 solucion 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 arbol 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 analize '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.
Pego la url tambien porque creo que es lo justo: http://www.todoexpertos.com/categori...nnect-by-prior
Saludos |