Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Bases de datos > Firebird e Interbase
Registrarse FAQ Miembros Calendario Guía de estilo Buscar Temas de Hoy Marcar Foros Como Leídos

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 07-04-2018
Avatar de Angel.Matilla
Angel.Matilla Angel.Matilla is offline
Miembro
 
Registrado: ene 2007
Posts: 1.350
Poder: 19
Angel.Matilla Va por buen camino
Error al definir una FOREIGN KEY

Tengo un BB.DD. en FB 2.5 con estas dos tablas:
Código:
CREATE TABLE Poblacion (CodPrv VARCHAR(2) DEFAULT '99' NOT NULL, Codigo INTEGER NOT NULL, 
Nombre VARCHAR(65) NOT NULL, Cpostal VARCHAR(10) NOT NULL, Pais VARCHAR(2) DEFAULT 'PD, 
CONSTRAINT PK_Poblacion PRIMARY KEY (CodPrv, Codigo))
Código:
CREATE TABLE DatLoc (CodPrv VARCHAR(2) DEFAULT '99' NOT NULL, Poblacion INTEGER NOT NULL, 
Actualiza TIMESTAMP, Padron INTEGER, Censo INTEGER, Concejales SMALLINT, 
Afiliados SMALLINT, Alcalde VARCHAR(60), Partido SMALLINT DEFAULT 1, 
Constitucion DATE, Sede VARCHAR(40), TlfSede VARCHAR(10), 
Presidente VARCHAR(60), TlfPres VARCHAR(10), Portavoz VARCHAR(60), 
TlfPort VARCHAR(10), Observaciones BLOB SUB_TYPE 1, 
CONSTRAINT PK_DatLoc PRIMARY KEY (CodPrv, Poblacion))
Y necesito definir una clave externa de la siguiente forma:
Código:
ALTER TABLE DATLOC ADD CONSTRAINT FK_DATLOC 
FOREIGN KEY (CODPRV,POBLACION) REFERENCES POBLACION(CODPRV,CODIGO) 
ON DELETE CASCADE ON UPDATE CASCADE;
Sin embargo, al ejecutar ese código me está dando este error:
Cita:
Unsuccessful metadata update.
Partner index segment no 1 has incompatible data type.

SQL Code: -607
IB Error Number: 335544351
El código del ALTER TABLE es el que me ha generado el propio SQL Manager y no acabo de ver dónde está el problema.
Responder Con Cita
  #2  
Antiguo 07-04-2018
Avatar de Casimiro Notevi
Casimiro Notevi Casimiro Notevi is offline
Moderador
 
Registrado: sep 2004
Ubicación: En algún lugar.
Posts: 32.021
Poder: 10
Casimiro Notevi Tiene un aura espectacularCasimiro Notevi Tiene un aura espectacular
CREATE TABLE Poblacion (
CodPrv VARCHAR(2) DEFAULT '99' NOT NULL,
Codigo INTEGER NOT NULL,
Nombre VARCHAR(65) NOT NULL,
Cpostal VARCHAR(10) NOT NULL,
Pais VARCHAR(2) DEFAULT 'PD, // <--- No has cerrado la comilla
CONSTRAINT PK_Poblacion PRIMARY KEY (CodPrv, Codigo))
Responder Con Cita
  #3  
Antiguo 07-04-2018
Avatar de Angel.Matilla
Angel.Matilla Angel.Matilla is offline
Miembro
 
Registrado: ene 2007
Posts: 1.350
Poder: 19
Angel.Matilla Va por buen camino
Esa errata ya la tengo corregida. De todas formas, cuando he ejecutado el ALTER TABLE ambas tablas ya existían. No acabo de ver dónde está el error. Lo que entiendo del mensaje de error es que los tipos de datos son distintos o ¿estoy equivocado?
Responder Con Cita
  #4  
Antiguo 07-04-2018
Avatar de ecfisa
ecfisa ecfisa is offline
Moderador
 
Registrado: dic 2005
Ubicación: Tres Arroyos, Argentina
Posts: 10.508
Poder: 36
ecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to behold
Hola.

Acabo de ejecutar tu código en un script:
Código SQL [-]
SET TERM ^ ;

CREATE TABLE POBLACION (
  CODPRV VARCHAR(2) DEFAULT '99' NOT NULL,
  CODIGO INTEGER NOT NULL,
  NOMBRE VARCHAR(65) NOT NULL,
  CPOSTAL VARCHAR(10) NOT NULL,
  PAIS VARCHAR(2) DEFAULT 'PD',
  CONSTRAINT PK_Poblacion PRIMARY KEY (CODPRV, CODIGO)
)^

CREATE TABLE DATLOC (
  CODPRV VARCHAR(2) DEFAULT '99' NOT NULL,
  POBLACION INTEGER NOT NULL,
  ACTUALIZA TIMESTAMP,
  PADRON INTEGER,
  CENSO INTEGER,
  CONCEJALES SMALLINT,
  AFILIADOS SMALLINT,
  ALCALDE VARCHAR(60),
  PARTIDO SMALLINT DEFAULT 1,
  CONSTITUCION DATE,
  SEDE VARCHAR(40),
  TLFSEDE VARCHAR(10),
  PRESIDENTE VARCHAR(60),
  TLFPRES VARCHAR(10),
  PORTAVOZ VARCHAR(60),
  TLFPORT VARCHAR(10),
  OBSERVACIONES BLOB SUB_TYPE 1,
  CONSTRAINT PK_DATLOC PRIMARY KEY (CODPRV, POBLACION)
) ^

ALTER TABLE DATLOC ADD CONSTRAINT
FK_DATLOC FOREIGN KEY(CODPRV, POBLACION)
REFERENCES POBLACION(CODPRV, CODIGO)
ON DELETE CASCADE ON UPDATE CASCADE ^

SET TERM ;^
y, aunque personalmente le daría otro nombre a la columna 'POBLACION' de la tabla DATLOC, no me genera ningún error en IBExpert .

Mi consulta es: ¿ Alguna de las tablas involucradas posee datos previos al momento de aplicar la nueva restricción ?

Saludos
__________________
Daniel Didriksen

Guía de estilo - Uso de las etiquetas - La otra guía de estilo ....
Responder Con Cita
  #5  
Antiguo 07-04-2018
Avatar de Angel.Matilla
Angel.Matilla Angel.Matilla is offline
Miembro
 
Registrado: ene 2007
Posts: 1.350
Poder: 19
Angel.Matilla Va por buen camino
Sí, la taba Poblacion tiene datos. Es una aplicación que ya está funcionando y hay que ampliar la base de datos con tablas nuevas.
Responder Con Cita
  #6  
Antiguo 07-04-2018
Avatar de ecfisa
ecfisa ecfisa is offline
Moderador
 
Registrado: dic 2005
Ubicación: Tres Arroyos, Argentina
Posts: 10.508
Poder: 36
ecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to behold
Hola.

Podría ser que algunos datos no cumplieran con la nueva restricción y eso te estuviera dando error. Por mi parte forcé la situación y el error que me genera IBExpert al aplicar la nueva restricción es:
Cita:
No es posible confirmar la transacción:
violation of FOREIGN KEY constraint "".
violation of FOREIGN KEY constraint "FK_DATLOC" on table "DATLOC".
Foreign key reference target does not exist.
Problematic key value is ("CODPRV" = '01', "POBLACION" = 3).
Sin embargo, el mensaje de error que publicas indica que la columna de la clave externa que estas creando es de diferente tipo al de la clave principal a que referencia, mas explayado aquí: Partner index segment no 1 has incompatible data type.

De todos modos podrías crear dos nuevas tablas sin datos (a modo de prueba) e intentar aplicarle la restricción y ver si te genera el error.

Saludos
__________________
Daniel Didriksen

Guía de estilo - Uso de las etiquetas - La otra guía de estilo ....
Responder Con Cita
  #7  
Antiguo 08-04-2018
Avatar de Angel.Matilla
Angel.Matilla Angel.Matilla is offline
Miembro
 
Registrado: ene 2007
Posts: 1.350
Poder: 19
Angel.Matilla Va por buen camino
Haré la prueba. No obstante el error me deja perplejo porque ambas columnas contienen el mismo tipo de datos.
Responder Con Cita
  #8  
Antiguo 09-04-2018
Avatar de Angel.Matilla
Angel.Matilla Angel.Matilla is offline
Miembro
 
Registrado: ene 2007
Posts: 1.350
Poder: 19
Angel.Matilla Va por buen camino
Estaba repasando el código que tengo hecho hasta ahora y me he dado cuenta de una cosa. Como comentaba lo que está pasando es que tengo que ampliar la base de datos de una aplicación ya existente; me he dado cuenta que en la carga inicial de datos, que proceden de una BB.DD. Paradox, las restricciones (CHECK y FOREIGN KEY) las defino después de haber cargado la tabla y no tuve ningún problema, y son unas cuantas.
Responder Con Cita
  #9  
Antiguo 09-04-2018
Avatar de Casimiro Notevi
Casimiro Notevi Casimiro Notevi is offline
Moderador
 
Registrado: sep 2004
Ubicación: En algún lugar.
Posts: 32.021
Poder: 10
Casimiro Notevi Tiene un aura espectacularCasimiro Notevi Tiene un aura espectacular
¿Paradox es una BD relacional?
Responder Con Cita
  #10  
Antiguo 09-04-2018
Avatar de Angel.Matilla
Angel.Matilla Angel.Matilla is offline
Miembro
 
Registrado: ene 2007
Posts: 1.350
Poder: 19
Angel.Matilla Va por buen camino
No, ya sé que no. Digo que los datos originales estaban tablas Paradox. Me refería a las restricciones en FB.
Responder Con Cita
  #11  
Antiguo 09-04-2018
Avatar de Casimiro Notevi
Casimiro Notevi Casimiro Notevi is offline
Moderador
 
Registrado: sep 2004
Ubicación: En algún lugar.
Posts: 32.021
Poder: 10
Casimiro Notevi Tiene un aura espectacularCasimiro Notevi Tiene un aura espectacular
Cita:
Empezado por Angel.Matilla Ver Mensaje
No, ya sé que no. Digo que los datos originales estaban tablas Paradox. Me refería a las restricciones en FB.
Es que en este caso en concreto, habría que ver esos datos que tienes. Paradox "se los traga" porque no es relacional.
Responder Con Cita
  #12  
Antiguo 09-04-2018
orodriguezca orodriguezca is offline
Miembro
 
Registrado: ene 2009
Posts: 221
Poder: 16
orodriguezca Va por buen camino
¿Los scripts SQL para crear las tabla POBLACION y DATLOC fueron obtenidos de la base de datos?. El mensaje de error indica que hay alguna discrepancia en la definición de la columna CODPRV entre las dos tabla, posiblemente el Collation.
Responder Con Cita
  #13  
Antiguo 09-04-2018
Avatar de Angel.Matilla
Angel.Matilla Angel.Matilla is offline
Miembro
 
Registrado: ene 2007
Posts: 1.350
Poder: 19
Angel.Matilla Va por buen camino
Cita:
Empezado por Casimiro Notevi Ver Mensaje
Es que en este caso en concreto, habría que ver esos datos que tienes. Paradox "se los traga" porque no es relacional.
A ver. En la BB.DD. Paradox hay columnas (en concreto CodPrv) que no están definidas, pero al hacer la carga de Paradox a FB ya lo tengo en cuenta y pongo un valro que sé no me va a dar error; en este caso concreto el valor que debe ir es 13 por la provincia de Ciudad Real y antes de ejecutar los INSERT correspondientes ya he cambiado el valor por defecto de 99 al que corresponde, 13 en este caso. Piensa que ambas bases de datos son "invento" mío.
Cita:
Empezado por orodriguezca Ver Mensaje
¿Los scripts SQL para crear las tabla POBLACION y DATLOC fueron obtenidos de la base de datos?. El mensaje de error indica que hay alguna discrepancia en la definición de la columna CODPRV entre las dos tabla, posiblemente el Collation.
Los scripts son código del programa Builder. Como puedes ver en ambos esa columna CodPrv está definida igual (VARCHAR(2)), lo mismo que esa columna Poblacion (que haciendo caso a ecfisa he bautizado de otra manera para evitar confusiones) es un entero en ambas tablas. Tal vez, y sólo tal vez, habría que definirlas como VARCHAR(3) o VARCHAR(4) ya que el avlro de ese campo podría llegar a ser 100. Y, por cierto, ¿a qué collation te refieres?
Responder Con Cita
  #14  
Antiguo 09-04-2018
Avatar de Angel.Matilla
Angel.Matilla Angel.Matilla is offline
Miembro
 
Registrado: ene 2007
Posts: 1.350
Poder: 19
Angel.Matilla Va por buen camino
A mi una de las cosas que más me sorprende es que en la carga inicial de la BB.DD. a partri de las tabals Paradox he podido hacer la definición de las restricciones DESPUÉS de cargar las tablas y ahora que tengo que definir nuevas tablas no me deja hacer esa definición.

Una cosa que se me ocurre, y seguramente será una burrada: La tabla DATLOC, como otras nuevas que hay que definir, es evidente que está vacía; dado que esta tabla no tiene datos y la tabla POBLACION no está vacía, ¿podría ser que el problema viniera por ahí? ¿Tal vez sería interesante crear un fila "fantasma" en DATLOC para evitar ese problema?
Responder Con Cita
  #15  
Antiguo 09-04-2018
Avatar de Casimiro Notevi
Casimiro Notevi Casimiro Notevi is offline
Moderador
 
Registrado: sep 2004
Ubicación: En algún lugar.
Posts: 32.021
Poder: 10
Casimiro Notevi Tiene un aura espectacularCasimiro Notevi Tiene un aura espectacular
No podemos hacer gran cosa sin tener los datos para probar.
Lo que es seguro, es que la base de datos tiene unas reglas fijas, es algo "matemático", y si dice que hay un problema con los datos, es que los hay.
Responder Con Cita
  #16  
Antiguo 09-04-2018
Avatar de Angel.Matilla
Angel.Matilla Angel.Matilla is offline
Miembro
 
Registrado: ene 2007
Posts: 1.350
Poder: 19
Angel.Matilla Va por buen camino
Creo que acabo de encontrar el error. Me parece que no tiene nada que ver con si una de las tablas tiene o datos; tiene que ver con que la propia tabla a que referencio (POBLACION en el caso que estoy comentando) tiene a su vez referencias externas. Lo digo porque he intentado volcar la tabla en otra con la misma estructura (pero sin índices ni nada más que los propios datos), vaciar la tabla inicial y al hacer el DELETE sobre ella me da error por otras tablas que tienen una clave externa sobre ella.

Se me ocurre, y lo tengo que probar, a eliminar todas estas claves externas ya existentes y volver a aplicarlas incluyendo las nuevas.
Responder Con Cita
  #17  
Antiguo 09-04-2018
orodriguezca orodriguezca is offline
Miembro
 
Registrado: ene 2009
Posts: 221
Poder: 16
orodriguezca Va por buen camino
Cita:
Empezado por Angel.Matilla Ver Mensaje
Y, por cierto, ¿a qué collation te refieres?
Me refiero a que cuando se crea una tabla se puede definir el collation_name de cada una de las columnas de tipo carácter. El siguiente es un fragmento de la sintaxis de la sentencia Create Table:

CREATE TABLE
Used for: creating a new table (relation)
Available in: DSQL, ESQL

Syntax:
CREATE [GLOBAL TEMPORARY] TABLE tablename
[EXTERNAL [FILE] '<filespec>']
(<col_def> [, {<col_def> | <tconstraint>} ...])
[ON COMMIT {DELETE | PRESERVE} ROWS];

<col_def> ::= <regular_col_def> | <computed_col_def>

<regular_col_def> ::=
colname {<datatype> | domainname}
[DEFAULT {literal | NULL | <context_var>}]
[NOT NULL]
[<col_constraint>]
[COLLATE collation_name]

Si se trata de establecer una integridad referencial entre dos tabla, entre columnas varchar, y si las columnas varchar tienen diferente collation_name saltará el error: Partner index segment no 1 has incompatible data type

En preguntas frecuentes de Firebird se encuentra lo siguiente:

"Partner index segment no 1 has incompatible data type

This usually means that the field in the foreign key you're trying to create has a different data type then the field of the primary key column it is referencing.

The difference can be subtle, anything that affects index (even field collation) is taken info account.

To solve this problem, usually the right thing to do is to change the data type of the foreign key columns before creating the foreign key constraint.
"



Edito: De ser posible borrar (drop table, no delete) ambas tablas y vuelve a crearlas.
Responder Con Cita
  #18  
Antiguo 10-04-2018
Avatar de Angel.Matilla
Angel.Matilla Angel.Matilla is offline
Miembro
 
Registrado: ene 2007
Posts: 1.350
Poder: 19
Angel.Matilla Va por buen camino
Gracias por la respuesta. No me había fijado en esa sintaxis; sin embargo, y haciendo caso a ecfisa, en la tabla DatLoc cambié el nombre de la columna por Codigo para que en ambas tablas se llamaran igual y tuvieran la misma estructura y por lo tanto en ambas ahora es: CodPrv VARCHAR(2) DEFAULT '99' NOT NULL, Codigo INTEGER NOT NULL, etc. Con esto la restricción quedaría así:
Código PHP:
ALTER TABLE DatLoc ADD CONSTRAINT FK_CodDatLoc FOREIGN KEY (CodPrvCodigoREFERENCES Poblacion(CodPrvCodigoON DELETE CASCADE ON UPDATE CASCADE 
Pero, a pesar de ello, se sigue generando el mismo error.

Sobre lo de eliminar la tabla y crearla de nuevo. Tengo el problema, que ya comenté ayer, que esa tabla Poblacion aplica restricciones en otras de la BB.DD. Estoy probando a borrar esas definiciones y crearlas de nuevo, pero no sé porqué (eso estoy investigando) no se ejecutan bien los querys.

Estoy haciendo esto, aunque empiezo a dudar que esté haciéndolo bien:
1. Tengo guardadas las definiciones en un array con la siguiente estructura:
Código PHP:
AnsiString cDefine[][3] = {{"CHK_ForPago" "Persona"   "ALTER TABLE Persona ADD CONSTRAINT CHK_ForPago CHECK (ForPago IN (SELECT Valor FROM Instalacion WHERE Etiqueta = 'ForPago'))"},
                           {
"CHK_PerPago" "Persona"   "ALTER TABLE Persona ADD CONSTRAINT CHK_PerPago CHECK (PerPago IN (SELECT Valor FROM Instalacion WHERE Etiqueta = 'PerPago'))"}, 
                           
etc
donde el primer elemento es el nombre de la restricción, el segundo el de la tabla sobre la que se aplica la misma y el tercero el código para crearla.
2. Verifico si existen todas las restricciones definidas en ese array.
Código PHP:
fMenu->Auxiliar->Close();
fMenu->Auxiliar->SQL->Text "SELECT * FROM RDB$CHECK_CONSTRAINTS WHERE RDB$CONSTRAINT_NAME = :Restriccion";

bool lPrueba true;
int nItem 0;
while (
cDefine[nItem][0] != "")
{
     
fMenu->Auxiliar->Close();
     
fMenu->Auxiliar->ParamByName("Restriccion")->AsString UpperCase(cDefine[nItem][0]);
     
fMenu->Auxiliar->Open();
     
lPrueba = !fMenu->Auxiliar->IsEmpty();
     if (!
lPrueba)
          break;
     
nItem ++;

3. De esta manera, si una de las restricciones que hay en el array no existe (lPrueba = false) es que hay que crearla y para curarme en salud intento borrar todas las que existen en ese momento. Para ello hago esto:
Código PHP:
fMenu->Auxiliar->Close();  // <-- Es el mismo query de más arriba
fMenu->Auxiliar->SQL->Text "SELECT * FROM RDB$CHECK_CONSTRAINTS WHERE RDB$CONSTRAINT_NAME = :Restriccion";

nItem 0;
while (
cDefine[nItem][0] != "")
{
     
fMenu->Auxiliar->Close();
     
fMenu->Auxiliar->ParamByName("Restriccion")->AsString UpperCase(cDefine[nItem][0]);
     
fMenu->Auxiliar->Open();

     if (!
fMenu->Auxiliar->IsEmpty())
     {
          try
          {
               
fMenu->Query->Close();
               
fMenu->Query->SQL->Text "ALTER TABLE " UpperCase(cDefine[nItem][1]) + " DROP CONSTRAINT " UpperCase(cDefine[nItem][0]);
               
fMenu->Query->ExecSQL();
               
fMenu->Query->Transaction->Commit();
          }
          catch(...)
          {
               
fMenu->Query->Transaction->Rollback();
          }
     }
     
nItem ++;

Veremos si así funcoona.
Responder Con Cita
  #19  
Antiguo 10-04-2018
Avatar de Angel.Matilla
Angel.Matilla Angel.Matilla is offline
Miembro
 
Registrado: ene 2007
Posts: 1.350
Poder: 19
Angel.Matilla Va por buen camino
Cita:
Empezado por Casimiro Notevi Ver Mensaje
No podemos hacer gran cosa sin tener los datos para probar.
Lo que es seguro, es que la base de datos tiene unas reglas fijas, es algo "matemático", y si dice que hay un problema con los datos, es que los hay.
No me importaría mandaros las tablas para que probarais. El problema es que el fichero, aun estando comprimido, ocupa más de 300 Mb

Última edición por Angel.Matilla fecha: 10-04-2018 a las 11:12:25.
Responder Con Cita
  #20  
Antiguo 10-04-2018
Avatar de Casimiro Notevi
Casimiro Notevi Casimiro Notevi is offline
Moderador
 
Registrado: sep 2004
Ubicación: En algún lugar.
Posts: 32.021
Poder: 10
Casimiro Notevi Tiene un aura espectacularCasimiro Notevi Tiene un aura espectacular
Si tiene datos personales, mejor que no lo envíes, por si acaso, ya sabes.
Responder Con Cita
Respuesta


Herramientas Buscar en Tema
Buscar en Tema:

Búsqueda Avanzada
Desplegado

Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro

Temas Similares
Tema Autor Foro Respuestas Último mensaje
Error al definir un FK en Firebird 2.5 Angel.Matilla Firebird e Interbase 10 29-11-2016 14:13:26
Error al intentar borrar constraint foreign key rfernandez Firebird e Interbase 5 09-10-2008 00:36:02
error al crear foreign key en firebird carlo_acp Conexión con bases de datos 2 23-02-2008 03:58:08
error de violation of foreign key constraint... en ibx Arturo Firebird e Interbase 1 07-12-2004 20:38:57
uso de FOREIGN KEY jzginez Firebird e Interbase 2 23-04-2004 00:20:25


La franja horaria es GMT +2. Ahora son las 18:50:39.


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
Copyright 1996-2007 Club Delphi