Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Firebird e Interbase (https://www.clubdelphi.com/foros/forumdisplay.php?f=19)
-   -   Extraer claves foraneas de BD (https://www.clubdelphi.com/foros/showthread.php?t=82068)

marcoszorrilla 23-01-2013 09:29:17

Extraer claves foraneas de BD
 
Tengo una BD Firebird 2.5, con 70 tablas y estoy intentando cambiar el ancho de un campo que es (PK clave primaria), me arroja un error y no me deja realizar el cambio, necesito ver todas las claves foráneas de la BD para encontrar la que me impide hacer el cambio, supongo que el asunto va por las tablas del sistema con las que me estoy peleando por el momento sin éxito.

Un Saludo.

Neftali [Germán.Estévez] 23-01-2013 10:32:35

Yo uso habitualmente IBExpert (version personal, free), y posee una pestaña que para cada objeto te da la información, de quien depende de él y de quien depende él.

Creo que es eso lo que buscas...


marcoszorrilla 23-01-2013 10:39:31

Gracias Neftalí, pero eso es lo que estoy haciendo, mirando cada tabla de las 70 que pienso está relacionada con la que no me deja ampliar el ancho, ya voy por la mitad.

Pensaba que en alguna tabla del sistema se guardan las claves foráneas y estaba intentando sin éxito utilizando ISQL extraer dichas claves para "ahorrar" tiempo.

Un Saludo.

Casimiro Notevi 23-01-2013 11:45:03

1 Archivos Adjunto(s)
También puedes extraer el metadata de la misma, además cuando pulsas en la tabla que quieres ver, en una de las pestañas, pone "dependencias", ahí te salen todas las tablas y campos foráneos de la misma.
Aquí tienes un ejemplo, lo de arriba son dependencias con tablas y lo de abajo con "vistas"

marcoszorrilla 23-01-2013 12:34:03

De momento sigo mirando tablas ya os diré en que queda el asunto.

Estoy usando Constraints---Foreign Key.

Un Saludo.

ecfisa 23-01-2013 14:07:23

Hola Marcos.

Para listar todas las claves foráneas, proba de este modo:
Código SQL [-]
SELECT RC.RDB$CONSTRAINT_NAME AS CONSTRAINT_NAME,
       I.RDB$RELATION_NAME AS TABLE_NAME,
       S.RDB$FIELD_NAME AS FIELD_NAME,
       I.RDB$DESCRIPTION AS DESCRIPTION,
       RC.RDB$DEFERRABLE AS IS_DEFERRABLE,
       RC.RDB$INITIALLY_DEFERRED AS IS_DEFERRED,
       REFC.RDB$UPDATE_RULE AS ON_UPDATE,
       REFC.RDB$DELETE_RULE AS ON_DELETE,
       REFC.RDB$MATCH_OPTION AS MATCH_TYPE,
       I2.RDB$RELATION_NAME AS REFERENCES_TABLE,
       S2.RDB$FIELD_NAME AS REFERENCES_FIELD,
       S.RDB$FIELD_POSITION + 1 AS FIELD_POSITION
FROM RDB$INDEX_SEGMENTS S
LEFT JOIN RDB$INDICES I ON I.RDB$INDEX_NAME = S.RDB$INDEX_NAME
LEFT JOIN RDB$RELATION_CONSTRAINTS RC ON RC.RDB$INDEX_NAME = S.RDB$INDEX_NAME
LEFT JOIN RDB$REF_CONSTRAINTS REFC ON RC.RDB$CONSTRAINT_NAME = REFC.RDB$CONSTRAINT_NAME
LEFT JOIN RDB$RELATION_CONSTRAINTS RC2 ON RC2.RDB$CONSTRAINT_NAME = REFC.RDB$CONST_NAME_UQ
LEFT JOIN RDB$INDICES I2 ON I2.RDB$INDEX_NAME = RC2.RDB$INDEX_NAME
LEFT JOIN RDB$INDEX_SEGMENTS S2 ON I2.RDB$INDEX_NAME = S2.RDB$INDEX_NAME
WHERE RC.RDB$CONSTRAINT_TYPE = 'FOREIGN KEY'
ORDER BY S.RDB$FIELD_POSITION

Saludos. :)

Neftali [Germán.Estévez] 23-01-2013 14:30:39

Cita:

Empezado por marcoszorrilla (Mensaje 453877)
...mirando cada tabla de las 70 que pienso está relacionada con la que no me deja ampliar el ancho, ya voy por la mitad.

No, si esta pantalla lo que te da son todas las relaciones que tiene tu tabla.

En la imagen puedes ver que, al marcar la tabla PROJECT, te está diciendo que hay otras 2 tablas que están relacionadas con esta (y los campos) y algunos procedimientos que también.



De esta forma, creo que puedes saber todas las tablas que tienen como clave foránea, la clave de tu tabla. Se supone que si ahí pones tu tabla, te dirá todas las otras cuya clave foránea apunta a la tuya.

O tal vez no te he entendido bien...

Neftali [Germán.Estévez] 23-01-2013 14:35:12

De todas formas, el propio IBExpert (que es mucho IBExpert) en la configuración tiene la opción de visualizar tablas de sistema.
Si con lo anterior no te vale, con esto deberías poder "chafardear" el diccionario de datos y obtener las relaciones.


beginner01 23-01-2013 15:26:11

Hola!.

Quizás este enlace sirva de ayuda.

marcoszorrilla 23-01-2013 16:09:58

Gracias a todos pero acabo de revisar todas las "ForeignKey" con el IbExpert y no es lo que creía, el problema según parece es que no me deja cambiar el ancho del campo CODIGO porque es una "PK" y tampoco me deja desactivar la "PK".

Cita:

update RDB$FIELDS set
RDB$FIELD_LENGTH = 12,
RDB$CHARACTER_LENGTH = 12
where RDB$FIELD_NAME = 'RDB$111'
Resultado:
Cita:

Unsuccessful execution caused by system error that does not preclude successful execution of subsequent statements.
action cancelled by trigger (1) to preserve data integrity.
Cannot update index segment used by an Integrity Constraint.

Un Saludo.

marcoszorrilla 23-01-2013 16:23:29

Cita:

CONSTRAINT_NAME TABLE_NAME FIELD_NAME DESCRIPTION IS_DEFERRABLE IS_DEFERRED ON_UPDATE ON_DELETE MATCH_TYPE REFERENCES_TABLE REFERENCES_FIELD FIELD_POSITION
=============================================================================== ===============================================================================
INTEG_72 ALBARUTA CODCLIENT <null> NO NO RESTRICT RESTRICT FULL CLIENTES CODIGO 1
INTEG_73 ALBARUTA VENDEDOR <null> NO NO RESTRICT RESTRICT FULL VENDEDORES CODIGO 1
INTEG_67 ALBARANES CODCLIENT <null> NO NO RESTRICT RESTRICT FULL CLIENTES CODIGO 1
INTEG_68 ALBARANES VENDEDOR <null> NO NO RESTRICT RESTRICT FULL VENDEDORES CODIGO 1
INTEG_15 LINAMORTIZA SBCUENTA <null> NO NO RESTRICT RESTRICT FULL AMORTIZA SBCUENTA 1
INTEG_97 LINCOMISIONES CODIGOMES <null> NO NO RESTRICT RESTRICT FULL COMISIONES CODIGOMES 1
INTEG_26 CLIENTES VENDEDOR <null> NO NO RESTRICT RESTRICT FULL VENDEDORES CODIGO 1
INTEG_157 LINEASGASTOS CONCEPTO <null> NO NO RESTRICT RESTRICT FULL GASTOS CONCEPTO 1
INTEG_83 LINEASVENTAS CODCLIENT <null> NO NO RESTRICT RESTRICT FULL CLIENTES CODIGO 1
INTEG_84 LINEASVENTAS VENDEDOR <null> NO NO RESTRICT RESTRICT FULL VENDEDORES CODIGO 1
INTEG_94 COMISIONES CODIGO <null> NO NO RESTRICT RESTRICT FULL VENDEDORES CODIGO 1
INTEG_107 TARIFAS GRUPO <null> NO NO RESTRICT RESTRICT FULL GRUPOTAR GRUPO 1
INTEG_53 ABONOS CODCLIENT <null> NO NO RESTRICT RESTRICT FULL CLIENTES CODIGO 1
INTEG_58 DEPOSITOS CODCLIENT <null> NO NO RESTRICT RESTRICT FULL CLIENTES CODIGO 1
INTEG_127 GASOIL MATRICULA <null> NO NO RESTRICT RESTRICT FULL VEHICULOS MATRICULA 1
INTEG_63 HDEPOSITOS CODCLIENT <null> NO NO RESTRICT RESTRICT FULL CLIENTES CODIGO 1
INTEG_111 COMPRAS CODIGO <null> NO NO RESTRICT RESTRICT FULL PROVEEDORES CODIGO 1
INTEG_100 LINREMESASRECIBOS REMESA <null> NO NO RESTRICT RESTRICT FULL REMESASRECIBOS REMESA 1
INTEG_41 PVPSP CODCLI <null> NO NO RESTRICT RESTRICT FULL CLIENTES CODIGO 1
INTEG_77 FACTURAS CODCLIENT <null> NO NO RESTRICT RESTRICT FULL CLIENTES CODIGO 1
INTEG_78 FACTURAS VENDEDOR <null> NO NO RESTRICT RESTRICT FULL VENDEDORES CODIGO 1
INTEG_34 MANTENIMIENTOS CODCLIENT <null> NO NO RESTRICT RESTRICT FULL CLIENTES CODIGO 1
INTEG_130 GASTOSVEHICULOS MATRICULA <null> NO NO RESTRICT RESTRICT FULL VEHICULOS MATRICULA 1

Con el metodo del compañero ECFISA. Lo he copiado a un fichero texto, he agregado un punto y coma al final;
y me devuelve lo que quiero, aunque he descubierto que ese no era el problema lo guardo porque es muy útil, se dirige la salida a un fichero de texto y ahí tienes todas las claves foraneas.

Un Saludo

Casimiro Notevi 23-01-2013 16:46:30

Veo que todos son integer, ¿qué quieres hacer exactamente?

marcoszorrilla 23-01-2013 17:01:11

No, Antonio, he pegado todas FK porque es muy útil extraerlas de una vez con el código de ECFISA, por si alguien le sirve más le pudiera servir.

En realidad lo que quiero hacer es cambiar el campo CODIGO de la tabla PVP que tiene ancho 10 a 12 (Varchar), pero no me deja porque es PK, no por Fk como pensaba.

Un Saludo.

Casimiro Notevi 23-01-2013 17:41:12

Bueno, claro, es primary key, pero desde las las otras tablas relacionadas son foreign key a esa primary key :)
Si tienes alguna tabla relacionada con ese campo entonces deberías desactivar en las relacionadas, modificar la primary* y luego volver a relacionar en las foreing.

* Y si no puedes modificarla, entonces crea una tabla nueva con la longitud que quieras y copias los datos de la tabla original a la nueva.

pd: por cierto, una primary key "es mejor" que sea integer, no varchar.

Al González 23-01-2013 19:12:30

Hola Marcos.

Se trata de un problema de dependencias. No puedes cambiar el campo que hace de llave primaria en una tabla (ni su tipo, ni su longitud, ni nada), sin antes desactivar las llaves externas, es decir, foráneas, que hay en otras tablas y que están relacionadas con esa primera tabla (llaves externas relacionadas con ese campo de llave primaria).

El diagrama de dependencias debería ser suficiente para averiguar qué tablas están "enganchadas" a la llave de la primera tabla. Es cosa de ubicarlas y eliminar su llave foránea de manera temporal. Haciendo lo anterior, podrás entonces eliminar la llave primaria con el fin de que ese campo quede "libre" para ser modificado.

Esto que dice Antonio es muy cierto:
Cita:

Empezado por Casimiro Notevi (Mensaje 453909)
pd: por cierto, una primary key "es mejor" que sea integer, no varchar.

^\||/
Soy un convencido de lo anterior. Doy a cada tabla una llave artificial, es decir, en todas ellas tengo un primer campo de tipo Integer llamado ID, el cual hago llave primaria y sirve también de enlace con llaves externas de otras tablas.

Venta.IDCliente "apunta" a Cliente.ID

Los campos "Codigo", "Clave", "Numero" son la "llave" para el usuario del sistema. Pero internamente, la verdadera llave primaria, es siempre el campo ID, el cual nunca es mostrado en pantalla o impreso en un reporte, puesto que su función es interna: ser la manija de cada registro.

Espero quede solucionado pronto.

Saludos.

Al.

marcoszorrilla 23-01-2013 21:28:09

No hay ninguna clave externa apuntando a la tabla PVP el único impedimento es que el campo a modificar es clave primaria y no me deja ni eliminar la clave, ni siquiera el propio campo, pero si me deja eliminar la tabla entera.

Lo que pienso hacer mañana:

1. Crear una tabla igual pero con otro nombre PVP1, esto lo haré con el IbExpert la opción DDL, copio y pego el código en Tools - Script Executive. aqui ya cambio el ancho del campo modificando el DDL antes de ejecutar.

2.-Creada la nueva tabla vacía, ejecuto un SQL: Insert Into PVP1 Select * from PVP;

3.-Elimino PVP y renombro PVP1.


Ya veremos lo que resulta.

Un Saludo.

ecfisa 24-01-2013 05:40:05

Cita:

Empezado por marcoszorrilla (Mensaje 453927)
No hay ninguna clave externa apuntando a la tabla PVP el único impedimento es que el campo a modificar es clave primaria y no me deja ni eliminar la clave, ni siquiera el propio campo, pero si me deja eliminar la tabla entera.

Hola de nuevo Marcos.

No sé si te sirva para el caso, pero suponiendo que ID es el nombre del campo y TABLA_PK el nombre de la restricción (PRIMARY KEY), para quitarla:
Código SQL [-]
ALTER TABLE TABLA DROP CONSTRAINT TABLA_PK

Para aplicarla nuevamente:
Código SQL [-]
ALTER TABLE TABLA ADD CONSTRAINT TABLA_PK PRIMARY KEY(ID)


Saludos.

marcoszorrilla 24-01-2013 06:50:07

Voy a realizar esa prueba, porque el IbExpert no me deja quitar la clave, veré si me deja por SQL.

Un Saludo.

marcoszorrilla 24-01-2013 10:44:11

Bueno gracias a todos y especialmente ECFISA, el SQL de su último mensaje ha funcioado.

Antecedentes:Cambiar el ancho del campo CODIGO Varchar(10) PK a 12.
Desde el IbExpert no deja cambiar el ancho, ni eliminar el campo porque es Clave primaria, tampoco deja desactivar la clave primaria.

Desde el ISQL ejecutando el SQL se soluciona todo.

Código SQL [-]
Código SQL [-]ALTER TABLE TABLA DROP CONSTRAINT TABLA_PK


Para aplicarla nuevamente despues de cambiar el ancho:
Código SQL [-]ALTER TABLE TABLA ADD CONSTRAINT TABLA_PK PRIMARY KEY(ID)


Un Saludo.

marcoszorrilla 24-01-2013 10:54:17

Finalmente he probado a ejecutar el código SQL desde el SQL EDITOR del IBExpert y ha funcionado.

1. Ejecutar codigo para quitar la Clave Primaria.
2. Editar el campo y luego su dominio para cambiar el ancho.
3. Ejecutar el código para restaurar la Clave Primaria.

No olvidar pulsar sobre el botón Commit.

Un Saludo.


La franja horaria es GMT +2. Ahora son las 11:31:47.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi