ActiveDelphi - Índice do Fórum ActiveDelphi
.: O site do programador Delphi! :.
 
 FAQFAQ   PesquisarPesquisar   MembrosMembros   GruposGrupos   RegistrarRegistrar 
 PerfilPerfil   Entrar e ver Mensagens ParticularesEntrar e ver Mensagens Particulares   EntrarEntrar 

Criar campo UNIQUE do firebird via delphi?

 
Novo Tópico   Responder Mensagem    ActiveDelphi - Índice do Fórum -> Banco de Dados
Exibir mensagem anterior :: Exibir próxima mensagem  
Autor Mensagem
adriano_servitec
Colaborador
Colaborador


Registrado: Sexta-Feira, 30 de Janeiro de 2004
Mensagens: 17618

MensagemEnviada: Ter Jan 19, 2021 4:12 pm    Assunto: Criar campo UNIQUE do firebird via delphi? Responder com Citação

Como faço para verificar se existe o campo UNIQUE do campo, se não tiver então criar e criar um index desse campo via Delphi?

Estou usando Firedac.
_________________
Jogo seu smartphone? Acesse o link e confira.
https://play.google.com/store/apps/details?id=br.com.couldsys.rockdrum
https://play.google.com/store/apps/details?id=br.com.couldsys.drumsetfree
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular
imex
Moderador
Moderador


Registrado: Sexta-Feira, 7 de Janeiro de 2011
Mensagens: 11666

MensagemEnviada: Ter Jan 19, 2021 5:21 pm    Assunto: Responder com Citação

Boa tarde,

Não sei ao certo qual componente do Firedac deve ser utilizado para execução de scripts, mas segue um exemplo de script que verifica se existe uma unique com o campo na tabela e cria se não existir:

Código:
execute block as
begin
  if (not exists
       (
         select * from rdb$indices as i
         inner join rdb$index_segments as s on i.rdb$index_name = s.rdb$index_name
         where i.rdb$unique_flag = 1 and i.rdb$relation_name = 'Tabela' and s.rdb$field_name = 'Campo'
       )
     ) then
    execute statement
      'alter table Tabela ADD CONSTRAINT NomeIndice unique (Campo)';
end


Espero que ajude


Editado pela última vez por imex em Qui Set 16, 2021 9:07 am, num total de 1 vez
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular
adriano_servitec
Colaborador
Colaborador


Registrado: Sexta-Feira, 30 de Janeiro de 2004
Mensagens: 17618

MensagemEnviada: Qua Jan 20, 2021 2:05 pm    Assunto: Responder com Citação

Boa tarde, até da certo, mais toda vez que eu vou chamar de novo gera um aviso

O método
Código:
procedure TDMConexao.Criar_Unique(const ANomeTabela, ANomeCampo, ANomeIndice: String);
var
  Qry: TFDQuery;
begin
  inherited;
  Qry := TFDQuery.Create(nil);
  try
    Qry.Connection := DMConexao.Connection;
    Qry.Close;
    Qry.SQL.Clear;
    Qry.SQL.Text :=
      ' EXECUTE BLOCK AS ' +
      ' BEGIN ' +
      '   IF (NOT EXISTS ' +
      '    (' +
      '       SELECT * FROM RDB$INDICES AS I ' +
      '   INNER JOIN RDB$INDEX_SEGMENTS AS S ON I.RDB$INDEX_NAME = S.RDB$INDEX_NAME ' +
      '        WHERE I.RDB$UNIQUE_FLAG = 1 AND ' +
      '              I.RDB$RELATION_NAME = ' + QuotedStr(ANomeTabela) +
      '          AND S.RDB$FIELD_NAME = ' + QuotedStr(ANomeCampo) +
      '    ) ' +
      ' ) THEN ' +
      '  EXECUTE STATEMENT ' +
      '  ''ALTER TABLE ' + ANomeTabela +
      '   ADD CONSTRAINT ' + ANomeIndice +
      '    UNIQUE ('+ ANomeCampo +')''; ' +
      '  END ';
     Qry.ExecSQL;
  finally
    Qry.Free;
  end;
end;


Esse método deixo no sistema ai tem que verificar se ja existe então não executar mais.

Só que ai ele está executando novamente e gera um aviso

Código:
---------------------------
[FireDAC][Phys][FB]unsuccessful metadata update

Index IDX_CD_USUARIO already exists

At block line: 1, col: 302.
---------------------------
OK   
---------------------------


Ai criei uma função para verificar se o index ja existe
Código:
function TDMConexao.VerificaExisteIndice(Conexao: TFDConnection;
  NomeIndice: String): Boolean;
var
  sSQL: String;
  Qry: TFDQuery;
begin
  Qry := TFDQuery.Create(nil);
  try
    Qry.Connection := Conexao;
    sSQL := 'SELECT RDB$INDEX_NAME FROM RDB$INDICES WHERE RDB$INDEX_NAME = ' +
      QuotedStr(UpperCase(NomeIndice));
    Qry.Close;
    Qry.SQL.Clear;
    Qry.SQL.Add(sSQL);
    Qry.Open;
    Result := (not Qry.IsEmpty);
  finally
    Qry.Free;
  end;
end;


Ai da certo, mais se la no metodo tem uma linha de verificação
Citação:
if (not exists
(
select * from rdb$indices as i

Não deveria ignorar? Ou estou fazendo errado?
_________________
Jogo seu smartphone? Acesse o link e confira.
https://play.google.com/store/apps/details?id=br.com.couldsys.rockdrum
https://play.google.com/store/apps/details?id=br.com.couldsys.drumsetfree
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular
imex
Moderador
Moderador


Registrado: Sexta-Feira, 7 de Janeiro de 2011
Mensagens: 11666

MensagemEnviada: Qua Jan 20, 2021 2:32 pm    Assunto: Responder com Citação

Boa tarde,

Com o "If Not Exists" o "Alter Table" não deveria ser executado quando a unique já existe.
Tente executar o script utilizando um TFDScript ou até mesmo o método ExecSQL do TFDConnection para ver se ocorre esse problema.
E você também pode testar o script através do IBExpert ou outra ferramenta semelhante para ver se também ocorre esse problema.

Espero que ajude
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular
adriano_servitec
Colaborador
Colaborador


Registrado: Sexta-Feira, 30 de Janeiro de 2004
Mensagens: 17618

MensagemEnviada: Qua Jan 20, 2021 2:52 pm    Assunto: Responder com Citação

imex escreveu:
Boa tarde,

Com o "If Not Exists" o "Alter Table" não deveria ser executado quando a unique já existe.
Tente executar o script utilizando um TFDScript ou até mesmo o método ExecSQL do TFDConnection para ver se ocorre esse problema.
E você também pode testar o script através do IBExpert ou outra ferramenta semelhante para ver se também ocorre esse problema.

Espero que ajude


Utilizando FDScript aparece o aviso em modo debbug, mais modo normal não

Código:
with FDScript do
  begin
    SQLScripts.Clear;
    SQLScripts.Add;
    with SQLScripts[0].SQL do
    begin
      Text :=
        ' EXECUTE BLOCK AS ' +
        ' BEGIN ' +
        '   IF (NOT EXISTS ' +
        '    (' +
        '       SELECT * FROM RDB$INDICES AS I ' +
        '   INNER JOIN RDB$INDEX_SEGMENTS AS S ON I.RDB$INDEX_NAME = S.RDB$INDEX_NAME ' +
        '        WHERE I.RDB$UNIQUE_FLAG = 1 AND ' +
        '              I.RDB$RELATION_NAME = ' + QuotedStr(ANomeTabela) +
        '          AND S.RDB$FIELD_NAME = ' + QuotedStr(ANomeCampo) +
        '    ) ' +
        ' ) THEN ' +
        '  EXECUTE STATEMENT ' +
        '  ''ALTER TABLE ' + ANomeTabela +
        '   ADD CONSTRAINT ' + ANomeIndice +
        '    UNIQUE ('+ ANomeCampo +')''; ' +
        '  END ';
    end;
    ValidateAll;
    ExecuteAll;
  end;

_________________
Jogo seu smartphone? Acesse o link e confira.
https://play.google.com/store/apps/details?id=br.com.couldsys.rockdrum
https://play.google.com/store/apps/details?id=br.com.couldsys.drumsetfree
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular
imex
Moderador
Moderador


Registrado: Sexta-Feira, 7 de Janeiro de 2011
Mensagens: 11666

MensagemEnviada: Qua Jan 20, 2021 3:47 pm    Assunto: Responder com Citação

Se você executar essa consulta que está dentro do exists no IBExpert ou ferramenta semelhante, ela retorna alguma coisa?
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular
adriano_servitec
Colaborador
Colaborador


Registrado: Sexta-Feira, 30 de Janeiro de 2004
Mensagens: 17618

MensagemEnviada: Qua Jan 20, 2021 4:03 pm    Assunto: Responder com Citação

imex escreveu:
Se você executar essa consulta que está dentro do exists no IBExpert ou ferramenta semelhante, ela retorna alguma coisa?


Sim
Olhe
Código:
can't format message 13:393 -- message file C:\Projeto\firebird.msg not found.
unsuccessful metadata update.
Index IDX_CD_USUARIO already exists.
At block line: 10, col: 8.

_________________
Jogo seu smartphone? Acesse o link e confira.
https://play.google.com/store/apps/details?id=br.com.couldsys.rockdrum
https://play.google.com/store/apps/details?id=br.com.couldsys.drumsetfree
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular
imex
Moderador
Moderador


Registrado: Sexta-Feira, 7 de Janeiro de 2011
Mensagens: 11666

MensagemEnviada: Qua Jan 20, 2021 4:30 pm    Assunto: Responder com Citação

Eu quis dizer esse trecho abaixo:

Código:
         select * from rdb$indices as i
         inner join rdb$index_segments as s on i.rdb$index_name = s.rdb$index_name
         where i.rdb$unique_flag = 1 and i.rdb$relation_name = 'Tabela' and s.rdb$field_name = 'Campo'


Se você executar essa consulta no IBExpert, ela retorna alguma coisa?
Se ela por algum motivo não retornar nada, poderíamos entender porque o "Alter Table" está sendo executado, e indicaria o trecho do script que estaria precisando ser analisado com mais detalhes.
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular
adriano_servitec
Colaborador
Colaborador


Registrado: Sexta-Feira, 30 de Janeiro de 2004
Mensagens: 17618

MensagemEnviada: Qua Jan 20, 2021 4:34 pm    Assunto: Responder com Citação

imex escreveu:
Eu quis dizer esse trecho abaixo:

Código:
         select * from rdb$indices as i
         inner join rdb$index_segments as s on i.rdb$index_name = s.rdb$index_name
         where i.rdb$unique_flag = 1 and i.rdb$relation_name = 'Tabela' and s.rdb$field_name = 'Campo'


Se você executar essa consulta no IBExpert, ela retorna alguma coisa?
Se ela por algum motivo não retornar nada, poderíamos entender porque o "Alter Table" está sendo executado, e indicaria o trecho do script que estaria precisando ser analisado com mais detalhes.


Não esta retornando nada. Tudo null
_________________
Jogo seu smartphone? Acesse o link e confira.
https://play.google.com/store/apps/details?id=br.com.couldsys.rockdrum
https://play.google.com/store/apps/details?id=br.com.couldsys.drumsetfree
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular
imex
Moderador
Moderador


Registrado: Sexta-Feira, 7 de Janeiro de 2011
Mensagens: 11666

MensagemEnviada: Qua Jan 20, 2021 4:45 pm    Assunto: Responder com Citação

Se você acha suficiente fazer a consulta somente pelo nome do índice, pode utilizar aquela consulta separada que você usou para ver se o índice já existe dentro do "Not Exists".
Sobre essa consulta que sugeri, acho que você teria que deixar de repente só o nome da tabela no Where para ver o que vai retornar e verificar qual filtro está fazendo com que não seja retornado nada.
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular
adriano_servitec
Colaborador
Colaborador


Registrado: Sexta-Feira, 30 de Janeiro de 2004
Mensagens: 17618

MensagemEnviada: Qua Jan 20, 2021 4:56 pm    Assunto: Responder com Citação

imex escreveu:
Se você acha suficiente fazer a consulta somente pelo nome do índice, pode utilizar aquela consulta separada que você usou para ver se o índice já existe dentro do "Not Exists".
Sobre essa consulta que sugeri, acho que você teria que deixar de repente só o nome da tabela no Where para ver o que vai retornar e verificar qual filtro está fazendo com que não seja retornado nada.
Ta bom, vou fazer assim então.

Obrigado
_________________
Jogo seu smartphone? Acesse o link e confira.
https://play.google.com/store/apps/details?id=br.com.couldsys.rockdrum
https://play.google.com/store/apps/details?id=br.com.couldsys.drumsetfree
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular
Mostrar os tópicos anteriores:   
Novo Tópico   Responder Mensagem    ActiveDelphi - Índice do Fórum -> Banco de Dados Todos os horários são GMT - 3 Horas
Página 1 de 1

 
Ir para:  
Enviar Mensagens Novas: Proibido.
Responder Tópicos Proibido
Editar Mensagens: Proibido.
Excluir Mensagens: Proibido.
Votar em Enquetes: Proibido.


Powered by phpBB © 2001, 2005 phpBB Group
Traduzido por: Suporte phpBB