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 (CodPrv, Codigo) REFERENCES Poblacion(CodPrv, Codigo) ON 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.