Erro quando vou salvar um novo registro.

Delphi

05/10/2023

Prezados Tenho a tabela abaixo e estou tentando inserir um novo registro e quando vou salvar,
aparece a mensagem " is not valid integer value". Meu procedimento também segue abaixo.
Alguém pode me ajudar? Obrigado.


CREATE TABLE Pessoa (
Id INTEGER PRIMARY KEY AUTOINCREMENT,
TipoCadastro VARCHAR (30) NOT NULL,
Nome VARCHAR (50) NOT NULL,
DataNascReg DATE,
CPFCNPJ VARCHAR (1Cool NOT NULL,
Telefone VARCHAR (16) NOT NULL,
Cidade VARCHAR (40) NOT NULL,
Bairro_Distrito VARCHAR (50) NOT NULL,
Estado CHAR (2) DEFAULT MG,
Email VARCHAR (80),
Ativo CHAR (1),
DataInicio DATE,
DataFim DATE
);


procedure TPageCadastroPessoa.btnSalvarClick(Sender: TObject);
begin
if Trim(CbTipo.Text) = '' then
begin
CbTipo.SetFocus;
Application.MessageBox('O campo Tipo de pessoa não pode ser vazio.', 'Atenção', MB_OK + MB_ICONWARNING);
abort;
end;

if Trim(edtNome.Text) = '' then
begin
edtNome.SetFocus;
Application.MessageBox('O campo Nome não pode ser vazio.', 'Atenção', MB_OK + MB_ICONWARNING);
abort;
end;

if Trim(edtCpfCnpj.Text) = '' then
begin
edtCPFCNPJ.SetFocus;
Application.MessageBox('O campo CPF\CNPJ não pode ser vazio.', 'Atenção', MB_OK + MB_ICONWARNING);
abort;
end;

if dmPessoas.cdsPessoas.State in [dsInsert] then
begin
dmPessoas.cdsPessoasid.AsInteger := StrToInt(EdtCodigo.Text);
end;
if dmPessoas.cdsPessoasTipoCadastro.AsString = ('Fornecedor') then
cbTipo.ItemIndex := 0
else if dmPessoas.cdsPessoasTipoCadastro.AsString = ('Parceiro Agrícola') then
cbTipo.ItemIndex := 1
else if dmPessoas.cdsPessoasTipoCadastro.AsString = ('Cliente') then
cbTipo.ItemIndex := 2
else dmPessoas.cdsPessoasTipoCadastro.AsString := (EmptyStr);
DMPessoas.cdsPessoasNome.AsString := edtNome.Text;
DmPessoas.cdsPessoasDataNascReg.AsDateTime := EdtDataNascReg.Date;
DMPessoas.cdsPessoasCpfCnpj.AsString := edtCpfCnpj.Text;
DMPessoas.cdsPessoasTelefone.AsString:= edtTelefone.Text ;
DmPessoas.cdsPessoasCidade.AsString := edtCidade.Text;
DMPessoas.cdsPessoasBairro_Distrito.AsString := edtBairro.Text;
DMPessoas.cdsPessoasEstado.AsString := edtEstado.Text;
DmPessoas.cdsPessoasEmail.AsString := edtEmail.Text;

if dmPessoas.cdsPessoasAtivo.AsString = ('S') then
cbAtivo.ItemIndex := 0
else if dmPessoas.cdsPessoasAtivo.AsString = ('N') then
cbAtivo.ItemIndex := 1
else
dmPessoas.cdsPessoasAtivo.AsString := (EmptyStr);
dmPessoas.cdsPessoasDataInicio.AsDateTime := edtDataInicio.Date;
dmPessoas.cdsPessoasDataFim.AsDatetime := edtDataFim.Date;

inherited;

end;
Mauricio Bomfim

Mauricio Bomfim

Curtidas 0

Melhor post

Emerson Nascimento

Emerson Nascimento

06/10/2023

o campo ID é autoincrentado. ainda assim você vai passar um conteúdo pra ele?

procedure TPageCadastroPessoa.btnSalvarClick(Sender: TObject);
const
  aTipoCadastro: TArray<String> = [' ', 'Fornecedor', 'Parceiro Agrícola', 'Cliente'];
  aAtivo: TArray<Char> = [' ', 'S', 'N'];
begin

	if Trim(CbTipo.Text) = '' then
	begin
		CbTipo.SetFocus;
		Application.MessageBox('O campo Tipo de pessoa não pode ser vazio.', 'Atenção', MB_OK + MB_ICONWARNING);
		abort;
	end;

	if Trim(edtNome.Text) = '' then
	begin
		edtNome.SetFocus;
		Application.MessageBox('O campo Nome não pode ser vazio.', 'Atenção', MB_OK + MB_ICONWARNING);
		abort;
	end;

	if Trim(edtCpfCnpj.Text) = '' then
	begin
		edtCPFCNPJ.SetFocus;
		Application.MessageBox('O campo CPF\\CNPJ não pode ser vazio.', 'Atenção', MB_OK + MB_ICONWARNING);
		abort;
	end;

	if (DMPessoas.cdsPessoas.State in [dsInsert]) then
		DMPessoas.cdsPessoasid.AsInteger := StrToInt(EdtCodigo.Text);

	// se eu entendi bem, você deve preencher o dataset a
	// partir dos componentes da tela, não o contrário

	DMPessoas.cdsPessoasTipoCadastro.AsString := aTipoCadastro[cbTipo.ItemIndex+1];
	DMPessoas.cdsPessoasDataNascReg.AsDateTime := EdtDataNascReg.Date;
	DMPessoas.cdsPessoasCpfCnpj.AsString := edtCpfCnpj.Text;
	DMPessoas.cdsPessoasTelefone.AsString := edtTelefone.Text;
	DMPessoas.cdsPessoasCidade.AsString := edtCidade.Text;
	DMPessoas.cdsPessoasBairro_Distrito.AsString := edtBairro.Text;
	DMPessoas.cdsPessoasEstado.AsString := edtEstado.Text;
	DMPessoas.cdsPessoasEmail.AsString := edtEmail.Text;
	DMPessoas.cdsPessoasAtivo.AsString := aAtivo[cbAtivo.ItemIndex+1];
	DMPessoas.cdsPessoasDataInicio.AsDateTime := edtDataInicio.Date;
	DMPessoas.cdsPessoasDataFim.AsDatetime := edtDataFim.Date;

	inherited;

end;
GOSTEI 1

Mais Respostas

Arthur Heinrich

Arthur Heinrich

05/10/2023

Provavelmente estou enganado, mas, sua coluna ID, que é a PK da tabela, possui a propriedade AUTOINCREMENT e, por ser uma PK, é NOT NULL.

Para que o AUTOINCREMENT seja utilizado, ao montar o comando insert você não pode fazer referência à coluna ID:

insert into Pessoa (TipoCadastro, Nome, DataNascReg, ...) values(...)

Porém, como você está fazendo o insert usando o componente, é possível que a coluna ID esteja sendo referenciada internamente e preenchida com valor NULL, já que nada foi atribuído a ela.
GOSTEI 0
Mauricio Bomfim

Mauricio Bomfim

05/10/2023

Excelente. Corrigi o código e agradeço a ajuda, pois ficou mais simplificado. Mas, agora quando vou salvar aparece o erro
"Field Value required". Pode me auxiliar novamente?





o campo ID é autoincrentado. ainda assim você vai passar um conteúdo pra ele?

procedure TPageCadastroPessoa.btnSalvarClick(Sender: TObject);
const
  aTipoCadastro: TArray<String> = [' ', 'Fornecedor', 'Parceiro Agrícola', 'Cliente'];
  aAtivo: TArray<Char> = [' ', 'S', 'N'];
begin

	if Trim(CbTipo.Text) = '' then
	begin
		CbTipo.SetFocus;
		Application.MessageBox('O campo Tipo de pessoa não pode ser vazio.', 'Atenção', MB_OK + MB_ICONWARNING);
		abort;
	end;

	if Trim(edtNome.Text) = '' then
	begin
		edtNome.SetFocus;
		Application.MessageBox('O campo Nome não pode ser vazio.', 'Atenção', MB_OK + MB_ICONWARNING);
		abort;
	end;

	if Trim(edtCpfCnpj.Text) = '' then
	begin
		edtCPFCNPJ.SetFocus;
		Application.MessageBox('O campo CPF\\\\CNPJ não pode ser vazio.', 'Atenção', MB_OK + MB_ICONWARNING);
		abort;
	end;

	if (DMPessoas.cdsPessoas.State in [dsInsert]) then
		DMPessoas.cdsPessoasid.AsInteger := StrToInt(EdtCodigo.Text);

	// se eu entendi bem, você deve preencher o dataset a
	// partir dos componentes da tela, não o contrário

	DMPessoas.cdsPessoasTipoCadastro.AsString := aTipoCadastro[cbTipo.ItemIndex+1];
	DMPessoas.cdsPessoasDataNascReg.AsDateTime := EdtDataNascReg.Date;
	DMPessoas.cdsPessoasCpfCnpj.AsString := edtCpfCnpj.Text;
	DMPessoas.cdsPessoasTelefone.AsString := edtTelefone.Text;
	DMPessoas.cdsPessoasCidade.AsString := edtCidade.Text;
	DMPessoas.cdsPessoasBairro_Distrito.AsString := edtBairro.Text;
	DMPessoas.cdsPessoasEstado.AsString := edtEstado.Text;
	DMPessoas.cdsPessoasEmail.AsString := edtEmail.Text;
	DMPessoas.cdsPessoasAtivo.AsString := aAtivo[cbAtivo.ItemIndex+1];
	DMPessoas.cdsPessoasDataInicio.AsDateTime := edtDataInicio.Date;
	DMPessoas.cdsPessoasDataFim.AsDatetime := edtDataFim.Date;

	inherited;

end;
GOSTEI 0
Mauricio Bomfim

Mauricio Bomfim

05/10/2023

Excelente. Corrigi o código e agradeço a ajuda, pois ficou mais simplificado. Mas, agora quando vou salvar aparece o erro
"Field Value required". Pode me auxiliar novamente?

Em tempo: Estou usando o SQLite e os componentes: FDQuery, DatasetProvider e um ClientDataset.
GOSTEI 0
Emerson Nascimento

Emerson Nascimento

05/10/2023

Certo. Agora temos um erro do banco de dados.

Eu penso da mesma forma que o Arthur Heinrich. Você tem um campo chave autoincremental que precisa de conteúdo.
O conteúdo deveria ter sido atribuído no trecho
if (DMPessoas.cdsPessoas.State in [dsInsert]) then
        DMPessoas.cdsPessoasid.AsInteger := StrToInt(EdtCodigo.Text);
Se não houve atribuição é porque o dataset não estava no estado de inserção.
Mas aí temos um problema de conceito. Um campo ID deve ser tratado como um campo interno, sem que o usuário precise ter conhecimento do seu conteúdo.
Olhando para a estrutura da tua tabela:
CREATE TABLE Pessoa (
	Id INTEGER PRIMARY KEY AUTOINCREMENT,
	TipoCadastro VARCHAR (30) NOT NULL,
	Nome VARCHAR (50) NOT NULL,
	DataNascReg DATE,
	CPFCNPJ VARCHAR (18) NOT NULL,
	Telefone VARCHAR (16) NOT NULL,
	Cidade VARCHAR (40) NOT NULL,
	Bairro_Distrito VARCHAR (50) NOT NULL,
	Estado CHAR (2) DEFAULT MG,
	Email VARCHAR (80),
	Ativo CHAR (1),
	DataInicio DATE,
	DataFim DATE
);
O campo que o usuário teria como "chave" seria o campo CPFCNPJ, que deveria ser marcado como único na tabela, para que não se repita dentro do cadastro.

Então, você não deveria fazer qualquer menção ao campo ID ao manipular o registro.
O campo ID seria somente para referência entre tabelas. Isto permitiria que um CPFCNPJ fosse corrigido no cadastro sem comprometer a chave estrangeira de outras tabelas (foreign key), pois o relacionamento entre as tabelas estaria sendo tratado a partir do campo ID.

Não conheço o SQLLite, mas em alguns SGBDR há o recurso de cascata (cascade) na alteração (update) ou na exclusão (delete). Isso quer dizer que:
- se você alterar o conteúdo do campo chave da tabela, esta alteração poderá ser replicada nas tabelas em que ele é ferenciado.
- se você excluir o registro da tabela, o banco de dados pode apagar a referência nas tabelas ("limpar" o campo) em que o registro é usado como chave estrangeira.
Nesse caso nem faz sentido existir um campo ID. Fica mais fácil deixar o próprio CPFCNPJ como chave primária e torná-lo chave estrangeira nas tabelas onde houver relacionamento com a tabela [Pessoa]. Assim, se o conteúdo do CPFCNPJ precisar ser alterado, o banco de dados se encarregará de alterar todas as fererências a ele.

Não sei se consegui ser claro na explicação.


GOSTEI 1
Natanael Ferreira

Natanael Ferreira

05/10/2023

Dê um duplo clique no seu FDQuery e Clientdataset e na lista de campos verifique se tem algum campo marcado a propriedade Required, se estiver desmarque e teste novamente.
GOSTEI 0
POSTAR