Firebird, Inclusão de Constraint Manual......
Olá Pessoal !!!
Estou com um problema tenho que incluir mais um campo como chave primaria mas o mesmo não deixa porque existe várias relacionamentos com esses campos. Então pesquisei nas system tables e consegui achar o local aonde fica armazenado os campos chaves de cada tabela, então resolvi criar um procedimento para adicionar o campo...... é:
CREATE PROCEDURE INCLUI_CAMPO_CHAVE_PRIMARIA (
PNOME_CHAVE_PRIMARIA VARCHAR(60),
PNOME_DA_TABELA VARCHAR(60),
PNOME_CAMPO VARCHAR(60))
AS
DECLARE VARIABLE INDECE VARCHAR(100);
DECLARE VARIABLE POSICAO_CAMPO INTEGER;
DECLARE VARIABLE EXISTE INTEGER;
begin
/* Este procedimento servirá para adicionar mais um campo na
Chave primária de uma tabela já existente que não pode ser
Excluida....
*/
SELECT R.RDB$INDEX_NAME FROM RDB$RELATION_CONSTRAINTS R
WHERE R.RDB$CONSTRAINT_NAME =:PNOME_CHAVE_PRIMARIA
AND R.RDB$RELATION_NAME=:PNOME_DA_TABELA
INTO :INDECE;
IF (INDECE IS NOT NULL ) THEN
BEGIN
/*
Inicializando a variável para fazer o teste
*/
EXISTE=-1;
/*
Verificando se o campo já não está incluido na chave primária
*/
SELECT P.RDB$FIELD_POSITION FROM RDB$INDEX_SEGMENTS P
WHERE
P.RDB$INDEX_NAME =:INDECE AND
P.RDB$FIELD_NAME =:PNOME_CAMPO
INTO :EXISTE;
IF (:EXISTE = -1 ) THEN
BEGIN
/*
Verificando qual é o próximo número de ordem da chave primária
*/
SELECT MAX(RDB$FIELD_POSITION)+1 AS PROXIMO FROM RDB$INDEX_SEGMENTS
WHERE
RDB$INDEX_NAME =:INDECE
INTO :POSICAO_CAMPO;
INSERT INTO RDB$INDEX_SEGMENTS(
RDB$INDEX_NAME /* NOME DO INDECE INTERNO NO FIREBIRD*/ ,
RDB$FIELD_NAME /* NOME DO CAMPO QUE DESEJA ADICIONAR A CHAVE PRIMARIA */,
RDB$FIELD_POSITION /* ORDEM DE ORDENACAO QUE APARECERÁ A TABELA */
)
VALUES
(:INDECE,:PNOME_CAMPO,:POSICAO_CAMPO);
END
END
suspend;
end
Até aqui tudo bem ele adiciona o campo que quiseres como campo da chave primária, mas só que não funciona, alguém sabe se esquici de alguma tabela.....
Desde já agradeço a ajuda de todos...
Ulisses
Estou com um problema tenho que incluir mais um campo como chave primaria mas o mesmo não deixa porque existe várias relacionamentos com esses campos. Então pesquisei nas system tables e consegui achar o local aonde fica armazenado os campos chaves de cada tabela, então resolvi criar um procedimento para adicionar o campo...... é:
CREATE PROCEDURE INCLUI_CAMPO_CHAVE_PRIMARIA (
PNOME_CHAVE_PRIMARIA VARCHAR(60),
PNOME_DA_TABELA VARCHAR(60),
PNOME_CAMPO VARCHAR(60))
AS
DECLARE VARIABLE INDECE VARCHAR(100);
DECLARE VARIABLE POSICAO_CAMPO INTEGER;
DECLARE VARIABLE EXISTE INTEGER;
begin
/* Este procedimento servirá para adicionar mais um campo na
Chave primária de uma tabela já existente que não pode ser
Excluida....
*/
SELECT R.RDB$INDEX_NAME FROM RDB$RELATION_CONSTRAINTS R
WHERE R.RDB$CONSTRAINT_NAME =:PNOME_CHAVE_PRIMARIA
AND R.RDB$RELATION_NAME=:PNOME_DA_TABELA
INTO :INDECE;
IF (INDECE IS NOT NULL ) THEN
BEGIN
/*
Inicializando a variável para fazer o teste
*/
EXISTE=-1;
/*
Verificando se o campo já não está incluido na chave primária
*/
SELECT P.RDB$FIELD_POSITION FROM RDB$INDEX_SEGMENTS P
WHERE
P.RDB$INDEX_NAME =:INDECE AND
P.RDB$FIELD_NAME =:PNOME_CAMPO
INTO :EXISTE;
IF (:EXISTE = -1 ) THEN
BEGIN
/*
Verificando qual é o próximo número de ordem da chave primária
*/
SELECT MAX(RDB$FIELD_POSITION)+1 AS PROXIMO FROM RDB$INDEX_SEGMENTS
WHERE
RDB$INDEX_NAME =:INDECE
INTO :POSICAO_CAMPO;
INSERT INTO RDB$INDEX_SEGMENTS(
RDB$INDEX_NAME /* NOME DO INDECE INTERNO NO FIREBIRD*/ ,
RDB$FIELD_NAME /* NOME DO CAMPO QUE DESEJA ADICIONAR A CHAVE PRIMARIA */,
RDB$FIELD_POSITION /* ORDEM DE ORDENACAO QUE APARECERÁ A TABELA */
)
VALUES
(:INDECE,:PNOME_CAMPO,:POSICAO_CAMPO);
END
END
suspend;
end
Até aqui tudo bem ele adiciona o campo que quiseres como campo da chave primária, mas só que não funciona, alguém sabe se esquici de alguma tabela.....
Desde já agradeço a ajuda de todos...
Ulisses
Ulissesn
Curtidas 0
Respostas
Afarias
23/03/2004
Não está correto fazer ´atualizações´ diretamente em tabelas de sistema do banco de dados -- Além do mais, vc não pode ter uma chave primária q difere das chaves estrangeiras relacionadas a ela.
Não é o q vc quer mas, o q vc tem q fazer é::
dropar todas as chaves estrangeiras q usam esta chave primária
dropar a chave primária
criar a nova chave primária (incluindo o novo campo)
re-criar todas as chaves estrangeiras (para a nova chave primária)
para tudo isso vc deve usar apenas o comando ALTER TABLE
ALTER TABLE tabela DROP CONSTRAINT ...
ALTER TABLE tabela ADD CONSTRAINT ...
T+
Não é o q vc quer mas, o q vc tem q fazer é::
dropar todas as chaves estrangeiras q usam esta chave primária
dropar a chave primária
criar a nova chave primária (incluindo o novo campo)
re-criar todas as chaves estrangeiras (para a nova chave primária)
para tudo isso vc deve usar apenas o comando ALTER TABLE
ALTER TABLE tabela DROP CONSTRAINT ...
ALTER TABLE tabela ADD CONSTRAINT ...
T+
GOSTEI 0
Ulissesn
23/03/2004
Tudo bem estou tentando deletar e dá a seguinte mensagem que está em uso .....
This operatio no defined for system tables
unsuccessfull metadata update.
Object index in use....
This operatio no defined for system tables
unsuccessfull metadata update.
Object index in use....
GOSTEI 0
Ulissesn
23/03/2004
Ah, esqueci de dizer isto acontece quando vou deletar a última chave estrangeira.....
GOSTEI 0
Afarias
23/03/2004
|Ah, esqueci de dizer isto acontece quando vou deletar a última chave
|estrangeira.....
como está o comando para DROPAR a chave estrangeira?
T+
|estrangeira.....
como está o comando para DROPAR a chave estrangeira?
T+
GOSTEI 0
Ulissesn
23/03/2004
O Camando dropar está assim:
ALTER TABLE CONTAS_RECEBER DROP CONSTRAINT FK_CONTAS_RECEBER_FILAL;
ALTER TABLE CONTAS_RECEBER DROP CONSTRAINT FK_CONTAS_RECEBER_FILAL;
GOSTEI 0
Afarias
23/03/2004
Humm... já experimentou desconectar/conectar no banco novamente e tentar o comando?? Não estou vendo motivo para o erro citado... (vc não fez as alterações nas tabelas de sistema neste banco não é mesmo)
Qualquer coisa, aproveite a faça um backup e restaure o banco e ai tente a alteração
T+
Qualquer coisa, aproveite a faça um backup e restaure o banco e ai tente a alteração
T+
GOSTEI 0