Verificando se o registro já existe
Amigos,
Utilizando SqlDataSet, DataSetProvider eClientDataSet, qual a melhor forma de verificar no momento da inclusão ou alteração se o registro já existe?
Estou utilizando mais um SqlDataSet no Form com o select e no momento de gravar veririfico SqlDataSet.IsEmpty.
Está correto?
Obrigado
Utilizando SqlDataSet, DataSetProvider eClientDataSet, qual a melhor forma de verificar no momento da inclusão ou alteração se o registro já existe?
Estou utilizando mais um SqlDataSet no Form com o select e no momento de gravar veririfico SqlDataSet.IsEmpty.
Está correto?
Obrigado
Lenasi
Curtidas 0
Respostas
Osocram
20/08/2009
Amigo...
Não entendi bem a sua dúvida.
Alteração - obrigatoriamente o resigistro tem q existir.
Inclusão - So vai existir o registro que vc esta incluindo se repetir a PK, geralmente se usa um Generator, AutoInc ou um Tabela Auxiliar. Para ter esse controle.
Agora fica algumas duvidas como vc esta incluindo isso?
É usando componente DBWare (dbedit e tal) ou vc esta gerando um script de insert?
Não entendi bem a sua dúvida.
Alteração - obrigatoriamente o resigistro tem q existir.
Inclusão - So vai existir o registro que vc esta incluindo se repetir a PK, geralmente se usa um Generator, AutoInc ou um Tabela Auxiliar. Para ter esse controle.
Agora fica algumas duvidas como vc esta incluindo isso?
É usando componente DBWare (dbedit e tal) ou vc esta gerando um script de insert?
Amigos,
Utilizando SqlDataSet, DataSetProvider eClientDataSet, qual a melhor forma de verificar no momento da inclusão ou alteração se o registro já existe?
Estou utilizando mais um SqlDataSet no Form com o select e no momento de gravar veririfico SqlDataSet.IsEmpty.
Está correto?
Obrigado
GOSTEI 0
Lenasi
20/08/2009
Bem amigo,
esqueci desse detalhe.
No banco utilizo o PK, isso já quer dizer que não pode repetir ok?
Como faço a verificação via código?
esqueci desse detalhe.
No banco utilizo o PK, isso já quer dizer que não pode repetir ok?
Como faço a verificação via código?
GOSTEI 0
Osocram
20/08/2009
O melhor é vc dar um exemplo de como vc usa ae.
Por exemplo Tabela de produto
id_produto (pk)
ds_produto
como é q vc gera o codigo do id_produto?
Ou é o usuário que digita?
Por exemplo Tabela de produto
id_produto (pk)
ds_produto
como é q vc gera o codigo do id_produto?
Ou é o usuário que digita?
Bem amigo,
esqueci desse detalhe.
No banco utilizo o PK, isso já quer dizer que não pode repetir ok?
Como faço a verificação via código?
GOSTEI 0
Discorpio
20/08/2009
Bom dia a todos.
A razão do nosso amigo é muito simples, ele quer evitar a duplicidade de registro no banco.
É tão simples que é rápido e rasteiro.
A melhor forma de se fazer isso é criar uma função booleana que retorne True, se o registro existir e False, se não existir.
Mas o por que de se criar a função :?:
Isto se faz necessário, porque voce tem que fazer a pesquisa antes de acionar o método Insert ou Append do componente TSQLDataSet, visto que ao se fazer a pesquisa, a tabela não pode estar aberta em modo de inserção porque haverá um scroll na tabela (movimentação de registros).
Vamos a função:
No botão Inserir, voce pode invocar a função dessa forma.
Não se esqueça de declarar a função no bloco Público ou Private da classe do Form, assim:
Lembrando também que com o DBExpress, voce deve fazer pesquisa com os componentes Unidirecionais tais como TSQLDataSet e TSQLQuery.
É recomendável até que voce coloque no um TSQLQuery somente para fazer isso (Pesquisa) e substitua o TSQLDataSet por ele na função.
Enquanto que as inserções, deleções e atualizações deverão ser sempre feitas pelo TClientDataSet.
A razão do nosso amigo é muito simples, ele quer evitar a duplicidade de registro no banco.
É tão simples que é rápido e rasteiro.
A melhor forma de se fazer isso é criar uma função booleana que retorne True, se o registro existir e False, se não existir.
Mas o por que de se criar a função :?:
Isto se faz necessário, porque voce tem que fazer a pesquisa antes de acionar o método Insert ou Append do componente TSQLDataSet, visto que ao se fazer a pesquisa, a tabela não pode estar aberta em modo de inserção porque haverá um scroll na tabela (movimentação de registros).
Vamos a função:
function TForm1.SearchRecord(AField): boolean; var Box, Sql: string; begin Result := False; Box := InputBox(´Pesquisando ´+AField,´Digite um valor para ´+AField); if Box = ´´ then ShowMessage(´Campo em branco ou operação cancelada´); else with SQLDataSet1 do begin Sql := ´Select * From tabela Where ´ + AField; Sql := Sql + ´ = :Param´; Close; CommandText := Sql; ParamByName(´Param´).Value := Box; Open; if Eof then ShowMessage(´Registro não encontrado´); else Result := True; end; end;
No botão Inserir, voce pode invocar a função dessa forma.
procedure TForm1.btnIncluirClick(Sender: TObject); begin if not SearchRecord(´NomedoCliente´) then ClientDataSet1.Append; end;
Não se esqueça de declarar a função no bloco Público ou Private da classe do Form, assim:
public
{ Public declarations }
function SearchRecord(AField): Boolean;
end;
Lembrando também que com o DBExpress, voce deve fazer pesquisa com os componentes Unidirecionais tais como TSQLDataSet e TSQLQuery.
É recomendável até que voce coloque no um TSQLQuery somente para fazer isso (Pesquisa) e substitua o TSQLDataSet por ele na função.
Enquanto que as inserções, deleções e atualizações deverão ser sempre feitas pelo TClientDataSet.
GOSTEI 0
Discorpio
20/08/2009
Olá, sou eu de novo.
Esqueci de incluir uma mensagem de registro encontrado na função:
Esqueci de incluir uma mensagem de registro encontrado na função:
function TForm1.SearchRecord(AField): boolean; var Box, Sql: string; begin Result := False; Box := InputBox(´Pesquisando ´+AField,´Digite um valor para ´+AField); if Box = ´´ then ShowMessage(´Campo em branco ou operação cancelada´); else with SQLDataSet1 do begin Sql := ´Select * From tabela Where ´ + AField; Sql := Sql + ´ = :Param´; Close; CommandText := Sql; ParamByName(´Param´).Value := Box; Open; if Eof then ShowMessage(´Registro não encontrado, pode inserir´); else begin ShowMessage(´Esse registro já existe´); Result := True; end; end;
GOSTEI 0
Lenasi
20/08/2009
É isso mesmo que precisava.... Vou testar depois respondo se deu certo...
Obrigado a todos por enquanto....
Obrigado a todos por enquanto....
GOSTEI 0
Lenasi
20/08/2009
Bom dia a todos.
Lembrando também que com o DBExpress, voce deve fazer pesquisa com os componentes Unidirecionais tais como TSQLDataSet e TSQLQuery.
É recomendável até que voce coloque no um TSQLQuery somente para fazer isso (Pesquisa) e substitua o TSQLDataSet por ele na função.
Ok, posso utilizar então o TSQLQuery com toda segurança?
Quando utilizaria então o TSQLDataSet?
Ao adicionar o Componente TSQLQuery, não preciso mexer nas Propriedades SQL e PARAMS, exceto o Name é claro???
Obrigado.
GOSTEI 0
Lenasi
20/08/2009
Amigo, no seu exemplo é para um campo apenas, ok?
No meu caso, preciso verificar se 4 tipos de informações já estão cadastradas....
No meu caso, preciso verificar se 4 tipos de informações já estão cadastradas....
GOSTEI 0
Discorpio
20/08/2009
Ok, posso utilizar então o TSQLQuery com toda segurança?
Quando utilizaria então o TSQLDataSet?
Ao adicionar o Componente TSQLQuery, não preciso mexer nas Propriedades SQL e PARAMS, exceto o Name é claro???
Obrigado.
É exatamente isso, o TSQLQuery, voce que que usar as linhas de comando´, assim:
... SQLQuery1.SQL.Clear; SQLQuery1.SQL.Add(´Select * From.........´); .....
Quanto o ParamByName ele pode continuar da mesma forma, pois ele existe de dois modos, assim:
SQLQuery1.ParamByName(...) SQLQuery1.Params.ParamByName(....)
GOSTEI 0
Discorpio
20/08/2009
Amigo, no seu exemplo é para um campo apenas, ok?
No meu caso, preciso verificar se 4 tipos de informações já estão cadastradas....
Voce quer dizer pesquisar 04 campos ao mesmo tempo, é isso :?:
GOSTEI 0
Lenasi
20/08/2009
[quote:f246e6e2ad=´lenasi´]
Voce quer dizer pesquisar 04 campos ao mesmo tempo, é isso :?:
Isso amigo...
Até consegui de uma outra forma que tinha como exemplo:
Veja:
if Ds.DataSet.State = dsInsert then SqModeloPesquisa.Close; SqModeloPesquisa.ParamByName(´PNMO_DESCRICAO´).AsString := DbEdDecricaoModelo.Text; SqModeloPesquisa.ParamByName(´PNMO_LINHA´).AsString := DBRadioModLinha.Value; SqModeloPesquisa.ParamByName(´PNMO_APLICACAO´).AsString := DBRadioModAplica.Value; SqModeloPesquisa.ParamByName(´PNFB_ID´).AsString := DbEdFabricaID.Text; SqModeloPesquisa.Open; IF not SqModeloPesquisa.IsEmpty Then Begin MessageDlg(´Registro já cadastrado !!!´,mtError,[mbok],0); SQModeloPesquisa.Close; Abort; End; SQModeloPesquisa.Close; inherited;
Mas estou tentando fazer o seguinte:
Isto funciona tanto na inclusão quanto na exclusão, e na verdade na Exclusão não poderia, ok?
Utilizei o comando (if Ds.DataSet.State = dsInsert then), mesmo quando estou no editando ele entra nesta função, e claro, dá que já existe!!!
O que pode ser neste caso?
GOSTEI 0
Lenasi
20/08/2009
[quote=´Discorpio´][quote:8f47eaf3c1=´lenasi´]
Mas estou tentando fazer o seguinte:
Isto funciona tanto na inclusão quanto na exclusão, e na verdade na Exclusão não poderia, ok?
RETIFICANDO: ALTERAÇÃO AO INVÉS DE EXCLUSÃO!!!
GOSTEI 0
Lenasi
20/08/2009
Resolvido :
Ficou assim:
Obrigadão à todos valeu mesmo !!!
Ficou assim:
if TClientDataSet(Ds.DataSet).State = dsInsert then Begin SqModeloPesquisa.Close; SqModeloPesquisa.ParamByName(´PNMO_DESCRICAO´).AsString := DbEdDecricaoModelo.Text; SqModeloPesquisa.ParamByName(´PNMO_LINHA´).AsString := DBRadioModLinha.Value; SqModeloPesquisa.ParamByName(´PNMO_APLICACAO´).AsString := DBRadioModAplica.Value; SqModeloPesquisa.ParamByName(´PNFB_ID´).AsString := DbEdFabricaID.Text; SqModeloPesquisa.Open; IF not SqModeloPesquisa.IsEmpty Then Begin MessageDlg(´Registro já cadastrado !!!´,mtError,[mbok],0); SQModeloPesquisa.Close; Abort; End; SQModeloPesquisa.Close; End;
Obrigadão à todos valeu mesmo !!!
GOSTEI 0
Discorpio
20/08/2009
Boa tarde a todos.
Lenasi
Voce está esquecendo de um pequeno detalhe, lembra do que eu disse lá atrás no meu post :?:
Sob hipótese nenhuma, voce deve invocar os métodos Append e Insert antes de fazer a pesquisa do registro.
Mas por que :?:
Por uma razão muito, simples, quando voce aciona Append ou Insert, o TClientDataSet, abre a tabela no DataSet Local, criando uma estrutura de registro em branco dentro da mesma, esperando que o usuário envie os registros para lá através do método Post. Ai eu te pergunto: O que vai acontecer se voce acionar uma pesquisa com SQL por exemplo :?: E aquela estrutura de linha de registro em branco, como ele ficou :?: Simplesmente ela não ficou, a linha em branco foi discartada, apesar de voce talvez, eu disse talvez de conseguir fazer a pesquisa, mas o Append ou Insert, como ficou :?:
Fazendo isso voce pode até corromper o índice do meio ou de final de tabela.
Como assim do meio ou do final ? Ai que entra as diferenças entre Append e Insert. O Insert abre uma linha em branco de onde estiver posicionado o ponteiro de registro, se estiver posicionado no ponteiro de número 25, por exemplo, ele abre a linha em branco posiconando o número 25 para baixo, passando esse ser o número 26. Já o Append acrescenta a linha em branco no final da tabela.
Por isso é fiz aquela função para que a mesma realize a pesquisa antes do Append ou Insert, se o registro for encontrado, eles não são acionados
Lenasi
Voce está esquecendo de um pequeno detalhe, lembra do que eu disse lá atrás no meu post :?:
......visto que ao se fazer a pesquisa, a tabela não pode estar aberta em modo de inserção porque haverá um scroll na tabela (movimentação de registros).
Sob hipótese nenhuma, voce deve invocar os métodos Append e Insert antes de fazer a pesquisa do registro.
Mas por que :?:
Por uma razão muito, simples, quando voce aciona Append ou Insert, o TClientDataSet, abre a tabela no DataSet Local, criando uma estrutura de registro em branco dentro da mesma, esperando que o usuário envie os registros para lá através do método Post. Ai eu te pergunto: O que vai acontecer se voce acionar uma pesquisa com SQL por exemplo :?: E aquela estrutura de linha de registro em branco, como ele ficou :?: Simplesmente ela não ficou, a linha em branco foi discartada, apesar de voce talvez, eu disse talvez de conseguir fazer a pesquisa, mas o Append ou Insert, como ficou :?:
Fazendo isso voce pode até corromper o índice do meio ou de final de tabela.
Como assim do meio ou do final ? Ai que entra as diferenças entre Append e Insert. O Insert abre uma linha em branco de onde estiver posicionado o ponteiro de registro, se estiver posicionado no ponteiro de número 25, por exemplo, ele abre a linha em branco posiconando o número 25 para baixo, passando esse ser o número 26. Já o Append acrescenta a linha em branco no final da tabela.
Por isso é fiz aquela função para que a mesma realize a pesquisa antes do Append ou Insert, se o registro for encontrado, eles não são acionados
GOSTEI 0
Lenasi
20/08/2009
Boa tarde a todos.
Lenasi
Voce está esquecendo de um pequeno detalhe, lembra do que eu disse lá atrás no meu post :?:
[quote:55d2510e4c=´discorpio´]
......visto que ao se fazer a pesquisa, a tabela não pode estar aberta em modo de inserção porque haverá um scroll na tabela (movimentação de registros).
Sob hipótese nenhuma, voce deve invocar os métodos Append e Insert antes de fazer a pesquisa do registro.
Mas por que :?:
Por uma razão muito, simples, quando voce aciona Append ou Insert, o TClientDataSet, abre a tabela no DataSet Local, criando uma estrutura de registro em branco dentro da mesma, esperando que o usuário envie os registros para lá através do método Post. Ai eu te pergunto: O que vai acontecer se voce acionar uma pesquisa com SQL por exemplo :?: E aquela estrutura de linha de registro em branco, como ele ficou :?: Simplesmente ela não ficou, a linha em branco foi discartada, apesar de voce talvez, eu disse talvez de conseguir fazer a pesquisa, mas o Append ou Insert, como ficou :?:
Fazendo isso voce pode até corromper o índice do meio ou de final de tabela.
Como assim do meio ou do final ? Ai que entra as diferenças entre Append e Insert. O Insert abre uma linha em branco de onde estiver posicionado o ponteiro de registro, se estiver posicionado no ponteiro de número 25, por exemplo, ele abre a linha em branco posiconando o número 25 para baixo, passando esse ser o número 26. Já o Append acrescenta a linha em branco no final da tabela.
Por isso é fiz aquela função para que a mesma realize a pesquisa antes do Append ou Insert, se o registro for encontrado, eles não são acionados[/quote:55d2510e4c]
Caro amigo,
estou meio confuso....
Deixa tentar entender:
O que eu fiz, foi dar um select(dentro do TSQLQuery) para buscar registros já cadastrados, e não uma pesquisa (ou é a mesma coisa?), enfim, o comando que passei, só executo quando vou gravar....
Mas me diz uma coisa: Como vou saber se já existe uma cadastrado ou não, se não houver primeiro uma tentativa de inclusão ou alteraração????
GOSTEI 0
Discorpio
20/08/2009
Boa tarde a todos.
Meu caro amigo Lenasi.
Qual é a lógica de buscar registros já cadastrados :?: :?: :?:
Somente quando voce quer alterar um registro específico e visualizar a sua alteração, ou simplesmente pesquisar as informações, correto :?:
No caso da Inserção, lógico que aqui voce quer evitar a duplicidade de registros, então, se por ventura o registro existir, qual é a lógica de acionar a inclusão :?: :?: :?: Voce pode simplesmente mostrar o registro já cadastrado e esta é uma opção.
Apesar de voce estar usando DBExpress, ou seja, voce estar fazendo a busca do Registros num TSQLQuery, enquanto que os demais registros encontram-se em cache local no TClientDataSet e só por causa disto, a sua aplicação funcionou, porque a busca foi feito no Servidor e não no cache local. Porém, é sempre bom ter o costume de se efetuar a pesquisa primeiro para acionar o Append ou Insert depois, pelo simples fato de amanhã depois voce trabalhar com uma aplicação monousuário e que os componentes mantém a ligação com o banco em tempo integral, como os componentes da palheta Interbase por exemplo, e também por questão da lógica já apresentada.
É lógico que para voce acionar a busca ou pesquisa de registros no momento em que voce queira incluir, voce deve acionar um button ou um MenuItem que vá antes de tudo realizar a pesquisa, e caso o registro não seja encontrado, ai sim dentro do evento OnClick desse Button ou MenuItem, voce aciona o append. Voce configurar um Botão de inclusão, não significa que voce deve de qualquer jeito abrir a tabela para inclusão, voce pode escrever um código dentro desse Evento que só abrirá a tabela para inclusão caso o registro não esteja cadastrado, dai o porque que escrevi aquela função.
Espero ter esclarecido
Meu caro amigo Lenasi.
Qual é a lógica de buscar registros já cadastrados :?: :?: :?:
Somente quando voce quer alterar um registro específico e visualizar a sua alteração, ou simplesmente pesquisar as informações, correto :?:
No caso da Inserção, lógico que aqui voce quer evitar a duplicidade de registros, então, se por ventura o registro existir, qual é a lógica de acionar a inclusão :?: :?: :?: Voce pode simplesmente mostrar o registro já cadastrado e esta é uma opção.
Apesar de voce estar usando DBExpress, ou seja, voce estar fazendo a busca do Registros num TSQLQuery, enquanto que os demais registros encontram-se em cache local no TClientDataSet e só por causa disto, a sua aplicação funcionou, porque a busca foi feito no Servidor e não no cache local. Porém, é sempre bom ter o costume de se efetuar a pesquisa primeiro para acionar o Append ou Insert depois, pelo simples fato de amanhã depois voce trabalhar com uma aplicação monousuário e que os componentes mantém a ligação com o banco em tempo integral, como os componentes da palheta Interbase por exemplo, e também por questão da lógica já apresentada.
É lógico que para voce acionar a busca ou pesquisa de registros no momento em que voce queira incluir, voce deve acionar um button ou um MenuItem que vá antes de tudo realizar a pesquisa, e caso o registro não seja encontrado, ai sim dentro do evento OnClick desse Button ou MenuItem, voce aciona o append. Voce configurar um Botão de inclusão, não significa que voce deve de qualquer jeito abrir a tabela para inclusão, voce pode escrever um código dentro desse Evento que só abrirá a tabela para inclusão caso o registro não esteja cadastrado, dai o porque que escrevi aquela função.
Espero ter esclarecido
GOSTEI 0
Lenasi
20/08/2009
Caro amigo,
Sabe o que não entra nesta minha cabeça dura?
Como que vou verificar uma duplicidade se o cadastro não estiver no modo de inserção?
O usuário clica no botão de INCLUIR, abre-se os campos para um novo registro e quando o mesmo digita as informações e clica em GRAVAR, daí verifico se já há um registro com as mesma especificações.... Entendeu?
Onde estou errando?
De que forma utilizaria sua função para verificar todos os campos(no caso são 4) se já não existe um registro igual?
Não teria, não pedindo mutio, me enviar um exemplo básico de um cadastro nesta situação? Pode ser um cadastro bem simples com dois campos por exemplo....
Mais uma vez obrigado....
Prometo que chegou lá !!!! rsrsss...
Sabe o que não entra nesta minha cabeça dura?
Como que vou verificar uma duplicidade se o cadastro não estiver no modo de inserção?
O usuário clica no botão de INCLUIR, abre-se os campos para um novo registro e quando o mesmo digita as informações e clica em GRAVAR, daí verifico se já há um registro com as mesma especificações.... Entendeu?
Onde estou errando?
De que forma utilizaria sua função para verificar todos os campos(no caso são 4) se já não existe um registro igual?
Não teria, não pedindo mutio, me enviar um exemplo básico de um cadastro nesta situação? Pode ser um cadastro bem simples com dois campos por exemplo....
Mais uma vez obrigado....
Prometo que chegou lá !!!! rsrsss...
GOSTEI 0
Osocram
20/08/2009
Eu acho.. que vcs estão discutindo coisas parecida mas diferentes....
Mas assim Lenasi, o que vc esta pensando esta certo tbm.
Vc esta incluindo um registro e antes de salvar ele vc fazer um select p ver se ja existe no banco de dados, ja que oq vc esta inserindo ainda esta somente na memoria do pc.
Mas assim Lenasi, o que vc esta pensando esta certo tbm.
Vc esta incluindo um registro e antes de salvar ele vc fazer um select p ver se ja existe no banco de dados, ja que oq vc esta inserindo ainda esta somente na memoria do pc.
Caro amigo,
Sabe o que não entra nesta minha cabeça dura?
Como que vou verificar uma duplicidade se o cadastro não estiver no modo de inserção?
O usuário clica no botão de INCLUIR, abre-se os campos para um novo registro e quando o mesmo digita as informações e clica em GRAVAR, daí verifico se já há um registro com as mesma especificações.... Entendeu?
Onde estou errando?
De que forma utilizaria sua função para verificar todos os campos(no caso são 4) se já não existe um registro igual?
Não teria, não pedindo mutio, me enviar um exemplo básico de um cadastro nesta situação? Pode ser um cadastro bem simples com dois campos por exemplo....
Mais uma vez obrigado....
Prometo que chegou lá !!!! rsrsss...
GOSTEI 0
Discorpio
20/08/2009
Boa dia a todos.
Caros amigos, não se trata só do nosso amigo Lenasi também estar certo, pois geralmente tudo que funciona não significa que esteja totalmente correto. Existe mais um motivo para seguir a regra da lógica que passei anteriomente, e uma delas é [color=red:b8c9ee6525]´Componentes ligado a dados´[/color:b8c9ee6525].
Muito embora, creio que já falei isso, a aplicação seja DBExpress, onde o componente TSQLQuery que consulta os dados possa não estar ligado a esses componentes que são ligado a dados (TDBEdit, TDBGrid e etc.), existe um outro fator que voce tem que levar em consideração que é quando voce aciona o método Append ou Insert do TClientDataSet, pois nesse momento, a tabela no cache local (ClientDataSet) e aberta e os componentes ligado a dados recebe um valor de pesquisa que vai acionar o TSQLQuery, se o registro existir, como fica o dado que foi digitado no componente TDBEdit :?: muito embora tenha invocado uma exceção silenciosa (Abort), porém não tratada, e que possívelmente não retornará de imediato o estado do ClientDataSet para modo ´Browse´ (Navegação), esse valor digitado poderá ser salvo no ClientDataSet indesejadamente, veja bem, e disse poderá (Atente para lei de Murphy), apesar de que o Abort gerando a exceção silenciosa não tratada, impede toda a execução sequencial, voltando ao estado anterior, estado esse que geralmente não é informado ao usuário, nesse momento em que estado está o Banco, em modo dsInsert, dsBrowse :?:
Dê uma olhada nesta apostila do link abaixo:
http://www.cpusoft.com.br/profmarcos/LPIII/delphi_bd_dbexpress.pdf
Nessa apostila aborda o seguinte trecho:
Caso voce insista em continuar com a sua lógica, nada impede de voce usá-la e mesma funcionar, só recomendo voce mudar a linha de comando que contém o Abort para ClientDataSet1.Cancel, pelo menos assim teremos uma garantia de que o estado do ClientDataSet1 mudará de dsInsert para dsBrowse e os valores digitados nos TDBEdits serão descartados.
Mas como vou passar os valores para pesquisa, que componentes usar :?: :?: :?:
Se voce observasse a função que passei, verificaria que ela utiliza uma função ´InputBox(...)´ que põe na tela uma caixa de diálogo com um componente TEdit, esperando que o usuário jogue um valor para dentro dela, onde o valor é jogado para dentro de uma variável Box, entretanto, voce quer pesquisar por mais de um campo e nesse caso eu recomendaria que voce elaborasse um Form só para pesquisa contendo TLabels com os nomes de todos os campos da tabela com os seus respectivos TEdits (não é ligado a dado) e um botão pesquisar, o código dentro desse form ficaria mais o menos assim:
[code]
procedure TfrmPesquisa.btnPesquisarClick(Sender: TObject);
begin
with FormPrincipal.SqModeloPesquisa do begin
Close;
SQL.Clear;
SQL.Add(´Select * From tabela Where 1 = 1 ´);
if EdtNome.Text <>´´ then begin
SQL.Add(´and Nome = :nome´);
ParamByName(´Nome´).Value := EdtNome.Text;
end else if (EdtTelefone.Text <> ´´) then begin
SQL.Add(´and Telefone = :tel´);
ParamByName(´tel´).Value := EdtTelefone.Text;
end else .......
.....
.....
end else if EdtPNMO_DESCRICAO.Text <> ´´ then begin
SQL.Add(´and PNMO_DESCRICAO = :desc´);
ParamByName(´desc´).Value := EdtPNMO_DESCRICAO.Text;
end;
Open
if Eof then begin
ShowMessage(´Registro não encontrado, pode inserir´)
FormPrincipal.ClientDataSet1.Append;
end else
ShowMessage(´Registro já cadastrado´);
end;
Self.Close;
end;
Repare duas coisas:
Eu fiz referência aos componentes SqModeloPesquisa e ClientDataSet que possívelmente estão no FormPrincipal, digitando primeiro a sua instância seguida de um ponto e em seguida o nome do componente, e isto só vai funcionar se voce declarar a Unit do FormPrincipal na Seção Uses do form de pesquisa.
Na Instrução SQL eu utilizei a condição Where 1=1, por que :?:
Simples, se porventura o usuário não digitar nada na primeira caixa de texto (TEdit) e digitar nas demais, a instrução SQL poderia ficar assim: ´Select * From tabela and campo = :campo and ....´, sem a cláusula Where gera erro, portanto é necessário que ele contenha pelo menos um critério que retorne True (1=1), então ficaria assim: ´Select * From tabela Where 1=1 and campo = :campo and ....
Caros amigos, não se trata só do nosso amigo Lenasi também estar certo, pois geralmente tudo que funciona não significa que esteja totalmente correto. Existe mais um motivo para seguir a regra da lógica que passei anteriomente, e uma delas é [color=red:b8c9ee6525]´Componentes ligado a dados´[/color:b8c9ee6525].
Muito embora, creio que já falei isso, a aplicação seja DBExpress, onde o componente TSQLQuery que consulta os dados possa não estar ligado a esses componentes que são ligado a dados (TDBEdit, TDBGrid e etc.), existe um outro fator que voce tem que levar em consideração que é quando voce aciona o método Append ou Insert do TClientDataSet, pois nesse momento, a tabela no cache local (ClientDataSet) e aberta e os componentes ligado a dados recebe um valor de pesquisa que vai acionar o TSQLQuery, se o registro existir, como fica o dado que foi digitado no componente TDBEdit :?: muito embora tenha invocado uma exceção silenciosa (Abort), porém não tratada, e que possívelmente não retornará de imediato o estado do ClientDataSet para modo ´Browse´ (Navegação), esse valor digitado poderá ser salvo no ClientDataSet indesejadamente, veja bem, e disse poderá (Atente para lei de Murphy), apesar de que o Abort gerando a exceção silenciosa não tratada, impede toda a execução sequencial, voltando ao estado anterior, estado esse que geralmente não é informado ao usuário, nesse momento em que estado está o Banco, em modo dsInsert, dsBrowse :?:
Dê uma olhada nesta apostila do link abaixo:
http://www.cpusoft.com.br/profmarcos/LPIII/delphi_bd_dbexpress.pdf
Nessa apostila aborda o seguinte trecho:
Post: Tenta enviar o novo registro ou o registro alterado para o banco de
dados. Se tudo correr bem, o DataSet é colocado no estado dsBrowse.
Caso contrário, o estado do DataSet não é alterado. O comando Post é
um tipo de confirmação da última entrada. Muitos componentes chamam Post automaticamente (quando se passa de um registro para outro em um DBGrid, por exemplo).
Caso voce insista em continuar com a sua lógica, nada impede de voce usá-la e mesma funcionar, só recomendo voce mudar a linha de comando que contém o Abort para ClientDataSet1.Cancel, pelo menos assim teremos uma garantia de que o estado do ClientDataSet1 mudará de dsInsert para dsBrowse e os valores digitados nos TDBEdits serão descartados.
Mas como vou passar os valores para pesquisa, que componentes usar :?: :?: :?:
Se voce observasse a função que passei, verificaria que ela utiliza uma função ´InputBox(...)´ que põe na tela uma caixa de diálogo com um componente TEdit, esperando que o usuário jogue um valor para dentro dela, onde o valor é jogado para dentro de uma variável Box, entretanto, voce quer pesquisar por mais de um campo e nesse caso eu recomendaria que voce elaborasse um Form só para pesquisa contendo TLabels com os nomes de todos os campos da tabela com os seus respectivos TEdits (não é ligado a dado) e um botão pesquisar, o código dentro desse form ficaria mais o menos assim:
[code]
procedure TfrmPesquisa.btnPesquisarClick(Sender: TObject);
begin
with FormPrincipal.SqModeloPesquisa do begin
Close;
SQL.Clear;
SQL.Add(´Select * From tabela Where 1 = 1 ´);
if EdtNome.Text <>´´ then begin
SQL.Add(´and Nome = :nome´);
ParamByName(´Nome´).Value := EdtNome.Text;
end else if (EdtTelefone.Text <> ´´) then begin
SQL.Add(´and Telefone = :tel´);
ParamByName(´tel´).Value := EdtTelefone.Text;
end else .......
.....
.....
end else if EdtPNMO_DESCRICAO.Text <> ´´ then begin
SQL.Add(´and PNMO_DESCRICAO = :desc´);
ParamByName(´desc´).Value := EdtPNMO_DESCRICAO.Text;
end;
Open
if Eof then begin
ShowMessage(´Registro não encontrado, pode inserir´)
FormPrincipal.ClientDataSet1.Append;
end else
ShowMessage(´Registro já cadastrado´);
end;
Self.Close;
end;
Repare duas coisas:
Eu fiz referência aos componentes SqModeloPesquisa e ClientDataSet que possívelmente estão no FormPrincipal, digitando primeiro a sua instância seguida de um ponto e em seguida o nome do componente, e isto só vai funcionar se voce declarar a Unit do FormPrincipal na Seção Uses do form de pesquisa.
Na Instrução SQL eu utilizei a condição Where 1=1, por que :?:
Simples, se porventura o usuário não digitar nada na primeira caixa de texto (TEdit) e digitar nas demais, a instrução SQL poderia ficar assim: ´Select * From tabela and campo = :campo and ....´, sem a cláusula Where gera erro, portanto é necessário que ele contenha pelo menos um critério que retorne True (1=1), então ficaria assim: ´Select * From tabela Where 1=1 and campo = :campo and ....
GOSTEI 0
Osocram
20/08/2009
Eu ja acho que usando este metodo do inputbox o usuario vai ter q digitar 2x os mesmos dados.
Então deveria fazer a verificação antes do aplyUpdates(0), e como tinha comentando o Discorpio, não é aconselhavel usar Abort;
faça algo do tipo
como usar
Então deveria fazer a verificação antes do aplyUpdates(0), e como tinha comentando o Discorpio, não é aconselhavel usar Abort;
faça algo do tipo
Function ValidaDuplicidade:boolean; begin result := false; if validou then begin ---- aqui fazer toda a rotina de validação... se passar por todas e tiver ok result := true; end; end;
como usar
cdsPrincipal.Post; if ValidaDuplicidade then cdsPrincipal.ApplyUpdate(0) else showmessage(´Por favor conferir os dados´); ----e deixa o usuario editar os dados errados p não ter que digitar tudo novamente
GOSTEI 0
Lenasi
20/08/2009
Eu ja acho que usando este metodo do inputbox o usuario vai ter q digitar 2x os mesmos dados.
Também concordo....
Eu não quero pesquisa antes, e sim validar o que está sendo digitado...
Então deveria fazer a verificação antes do aplyUpdates(0), e como tinha comentando o Discorpio, não é aconselhavel usar Abort;
Mas o meu cmando está sendo executado antes o AppyUpdate(0)...
Deixa colocar novamente os comandos:
Após clicar no botão de INCLUIR:
if not Ds.DataSet.Active then Ds.DataSet.Open; Ds.DataSet.Insert;
Após clicar no botão de GRAVAR: É Claro, ante do TClientDataSet(Ds.DataSet).ApplyUpdates(0);
========================================
if TClientDataSet(Ds.DataSet).State = dsInsert then Begin SqModeloPesquisa.Close; SqModeloPesquisa.ParamByName(´PNMO_DESCRICAO´).AsString := DbEdDecricaoModelo.Text; SqModeloPesquisa.ParamByName(´PNMO_LINHA´).AsString := DBRadioModLinha.Value; SqModeloPesquisa.ParamByName(´PNMO_APLICACAO´).AsString := DBRadioModAplica.Value; SqModeloPesquisa.ParamByName(´PNFB_ID´).AsString := DbEdFabricaID.Text; SqModeloPesquisa.Open; IF not SqModeloPesquisa.IsEmpty Then Begin MessageDlg(´Registro já cadastrado !!!´,mtError,[mbok],0); SQModeloPesquisa.Close; Abort; End; SQModeloPesquisa.Close; End; .... .... TClientDataSet(Ds.DataSet).ApplyUpdates(0);
GOSTEI 0
Lenasi
20/08/2009
??
GOSTEI 0
Osocram
20/08/2009
Certo.. a tua logica eu acho que esta certo sim.
A unica coisa que deve tormar cuidado é em usar o Abort;
Abort gera uma exceção silenciosa, o que não é mto bom, ja que vc sabe o que esta acontecendo e vc mesmo pode tratar de uma forma melhor.
pegue esse seu codigo antes do apply e faça uma função
Usaria assim:
O que vc esta querendo fazer provavelmente funciona mas é bom evitar usar o abort;
Por isso sugiro este modo usando um metodo de validação desta maneira fica flexivel p vc pudar onde vc quer fazer esta validação.
A unica coisa que deve tormar cuidado é em usar o Abort;
Abort gera uma exceção silenciosa, o que não é mto bom, ja que vc sabe o que esta acontecendo e vc mesmo pode tratar de uma forma melhor.
SqModeloPesquisa.Open; IF not SqModeloPesquisa.IsEmpty Then Begin MessageDlg(´Registro já cadastrado !!!´,mtError,[mbok],0); SQModeloPesquisa.Close; Abort; <----- isso aqui não é bom, End; SQModeloPesquisa.Close; End; .... .... TClientDataSet(Ds.DataSet).ApplyUpdates(0);
pegue esse seu codigo antes do apply e faça uma função
function ExisteRegistroDuplicado:Boolean; begin result := true; SqModeloPesquisa.Close; SqModeloPesquisa.ParamByName(´PNMO_DESCRICAO´).AsString := DbEdDecricaoModelo.Text; SqModeloPesquisa.ParamByName(´PNMO_LINHA´).AsString := DBRadioModLinha.Value; SqModeloPesquisa.ParamByName(´PNMO_APLICACAO´).AsString := DBRadioModAplica.Value; SqModeloPesquisa.ParamByName(´PNFB_ID´).AsString := DbEdFabricaID.Text; SqModeloPesquisa.Open; IF SqModeloPesquisa.IsEmpty Then result := false; SQModeloPesquisa.Close; End; end;
Usaria assim:
if ExisteRegistroDuplicado then begin MessageDlg(´Registro já cadastrado !!!´,mtError,[mbok],0); exit; end; .... .... TClientDataSet(Ds.DataSet).ApplyUpdates(0);
O que vc esta querendo fazer provavelmente funciona mas é bom evitar usar o abort;
Por isso sugiro este modo usando um metodo de validação desta maneira fica flexivel p vc pudar onde vc quer fazer esta validação.
Isso é uma boa prática de programação.
GOSTEI 0
Lenasi
20/08/2009
Certo.. a tua logica eu acho que esta certo sim.
[quote:d12bcc7cbc]Isso é uma boa prática de programação.
[/quote:d12bcc7cbc]Ok amigo,
Vou adaptar, testar hoje a noite depois digo como ficou...
Muito obrigado.
GOSTEI 0