Jump to content
Fórum Script Brasil
  • 0

[resolvido] Multiusuarios


Eder
 Share

Question

Ola..pessoal..

Eu tenho um pequeno aplicativo que já fiz a anos atraz...paradox e com campo dipo N-NUMERICO pra controlar as entradas

a tabela = VISBLU é a master

codigo (N)

a tabela = IVISBLU é a detalhes

CodVisita(N)

o codigo VISBLU.CODIGO = IVISBLU.CODVISITA (relacionamento)

Funciona tudo certinho quando um usuario somente usa...se entrar outro usuario, da erro de Key

Codigo do botão NOVO REGISTRO da MASTER

procedure TFormCVisita.XiButton1Click(Sender: TObject);
var
proxnum: integer; // variavel para inserir um proximo numero
begin
if application.messagebox('Deseja Incluir um Novo Registro?','Aviso',36)=idYes
then
begin
table1.Last;
ProxNum:= table1.fieldbyName('CODIGO').AsInteger +1;
table1.Append;
table1.FieldByName('CODIGO').AsInteger :=ProxNum;
EditData.SETFOCUS;
end else    //CANCELA OPERAÇÃO
table1.cancel;
end;
Codigo do botão NOVO REGISTRO da DETALHES
procedure TFormCVisita.XiButton5Click(Sender: TObject);
var
proxnum: integer; // variavel para inserir um proximo numero
BEGIN
table2.Last;
ProxNum:= table2.fieldbyName('CODITEM').AsInteger +1;
table2.Append;
table2.FieldByName('CODITEM').AsInteger :=ProxNum;
DBLookupComboBox1.setfocus;                
dBLookupComboBox1.CanFocus;
END;

Teria como corrigir esta situação permitindo que o programa aceita mais de um usuario digitando??

Grato

Edited by Micheus
Link to comment
Share on other sites

24 answers to this question

Recommended Posts

  • 0

Eder, este é o problema típico da "metodologia" que era utilizada para aplicações mono-usuário e que são aplicadas às multi-usuários.

Você só deve obter o "código incremental" apenas no momento em que vai gravar a informação.

Quando você tem apenas um usuário acessando o banco, sem problemas. Mas, quando mais que um podem iniciar uma inclusão simultaneamente, é garantido que ambos oberão o mesmo valor. Como resultado, o primeiro a gravar, consegue manter o número obtido, mas o segundo tentará gravar um código (chave) que já existe - resultado: "Key violation".

Dá uma olhada nestes outros 2 posts que seriam sugestões para contornar a questão:

post 1

post 2

Qualquer dúvida extra é só postar aqui.

Abraços

Link to comment
Share on other sites

  • 0

Ola...

Eder, este é o problema típico da "metodologia" que era utilizada para aplicações mono-usuário e que são aplicadas às multi-usuários.

Você só deve obter o "código incremental" apenas no momento em que vai gravar a informação.

Quando você tem apenas um usuário acessando o banco, sem problemas. Mas, quando mais que um podem iniciar uma inclusão simultaneamente, é garantido que ambos oberão o mesmo valor. Como resultado, o primeiro a gravar, consegue manter o número obtido, mas o segundo tentará gravar um código (chave) que já existe - resultado: "Key violation".

R.: Entendi

Ref..ao segundo post mencionado:

post 2

eu alterei o codigo assim:

Query2Codigo.SQL.Clear;

Query2Codigo.SQL.Add('Select MAX(codigo) from VISBLU order by codigo');

Query2Codigo.SQL.Open;

Table1Codigo.Value := QryCodigo.Fields[0].AsInteger +1;

da erro na primeira linha

[Error] LCVisita.pas(410): Undeclared identifier: 'SQL'

Porque este erro? :(

Haaa...outra coisinha...aplicando desta forma...como ficaria o codigo no botão de NOVO REGISTRO?? já que estou incrementando diretamente na BeforePost da Table.

Grato

Link to comment
Share on other sites

  • 0
Ref..ao segundo post mencionado:
post 2

eu alterei o codigo assim:

Query2Codigo.SQL.Clear;

Query2Codigo.SQL.Add('Select MAX(codigo) from VISBLU order by codigo');

Query2Codigo.SQL.Open;

Table1Codigo.Value := QryCodigo.Fields[0].AsInteger +1;

da erro na primeira linha

[Error] LCVisita.pas(410): Undeclared identifier: 'SQL'

Porque este erro? :(

porque você copiou ao pé da letra. Tem que captar a idéia apenas. estou achando que você simplesmente renomeou um componente TTable para Query2Codigo. É isso?

SQL é uma propriedade de um TQuery, se você o utilizou teria que ter. Que componente você está utilizando?

Áh!!! pode tirar aquele order by <nome_campo> que eu coloquei porque não tem a menor necessidade - foi barberagem mesmo.

Haaa...outra coisinha...aplicando desta forma...como ficaria o codigo no botão de NOVO REGISTRO?? já que estou incrementando diretamente na BeforePost da Table.
A única coisa que deve mudar em seu código é que você não inicializa mais o campo que é incremental. Você só tem este valor no momento que vai gravar.

Outra coisa, em mestre detalhe, para gravar o detalhe, o mestre já tem que estar salvo. Então, quando você for incluir um novo item, já deverá ter gravado o header para poder utilizar o código gerado no BeforePost dele.

Link to comment
Share on other sites

  • 0
porque você copiou ao pé da letra. Tem que captar a idéia apenas. estou achando que você simplesmente renomeou um componente TTable para Query2Codigo. É isso?
R.: não..eu adicionei um TQuery...O TQuery não aceita da maneira como você colocou(somente os TTable aceita desta forma.....acho eu...não tenho certeza..acho que já passei uma vez por isto.)

ai fiz assim:

Query2Codigo.SQL.Clear;

Query2Codigo.SQL.Add('Select MAX(codigo) from VISBLU order by codigo');

Query2Codigo.SQL.Open;

Table1Codigo.Value := QryCodigo.Fields[0].AsInteger +1

ai aceitou.....mas deu erro na ultima linha do table:

[Error] LCVisita.pas(414): Undeclared identifier: 'Fields'

SQL é uma propriedade de um TQuery, se você o utilizou teria que ter. Que componente você está utilizando?

Áh!!! pode tirar aquele order by <nome_campo> que eu coloquei porque não tem a menor necessidade - foi barberagem mesmo:

Áh!!! pode tirar aquele order by <nome_campo> que eu coloquei porque não tem a menor necessidade - foi barberagem mesmo.

R. Ok...já tirei..eu também esqueci.

Grato.

Link to comment
Share on other sites

  • 0
ai fiz assim:
Query2Codigo.SQL.Clear;

Query2Codigo.SQL.Add('Select MAX(codigo) from VISBLU order by codigo');

Query2Codigo.SQL.Open;

Table1Codigo.Value := QryCodigo.Fields[0].AsInteger +1

ai aceitou.....mas deu erro na ultima linha do table:

[Error] LCVisita.pas(414): Undeclared identifier: 'Fields'

ainda tem algo estranho:

depois de Query2Codigo.Open, onde é que deve estar o resultado do MAX? Acho que no Query2Codigo.Fields[0].AsInteger.

De onde saiu este QryCodigo.Fields[0].AsInteger?

Link to comment
Share on other sites

  • 0

Opa...Micheus

Abaixo explica acho eu tudo...acho que te confundi....né. ;)

consegui assim Na MASTER e deu certo :D :

Pois na Master é incrementar + 1 (sempre)

With Query2 Do
Begin
Close;
With SQL Do
Begin
Clear;
Add('Select VISBLU.CODIGO From VISBLU ORDER BY CODIGO');
end;
OPEN;
Query2.LAST;
Table1Codigo.Value := Query2Codigo.AsInteger +1;
end;
Agora na DETALHES ai não funciona...pois a cada virada do codigo da MASTER a detalhes tem que zerar e começar de novo....ai não to conseguindo fazer funcionar. exemplo: No dbgrid da detalhes aparece assim(note que a cada mudança da master o coditem vira e começa a contar de novo:
CodMaster--coditem(contador)
       1              1
       1              2
       1              3
       2              1
       2              2
       3              1
       3              2
       3              3
e assim por diante(acho que você irá entender).
Podes por favor me dar uma dica?? tentei assim mas ele só conta o primeiro registro, apartir do segundo da erro de keyViolation, pois ele sempre me mostra o nr 1:
With Query3 Do
Begin
Close;
With SQL Do
Begin
Clear;
Add('Select IVISBLU.CODITEM From IVISBLU ORDER BY CODITEM');
end;
OPEN;
Table2CODITEM.Value := Query3CodITEM.AsInteger +1;
end;

muito Grato

Edited by Eder
Link to comment
Share on other sites

  • 0
Abaixo explica acho eu tudo...acho que te confundi....né. ;)
podes crêr...

Agora na DETALHES ai não funciona...pois a cada virada do codigo da MASTER a detalhes tem que zerar e começar de novo....ai não to conseguindo fazer funcionar.

Podes por favor me dar uma dica??

tentei assim mas ele só conta o primeiro registro, apartir do segundo da erro de keyViolation, pois ele sempre me mostra o nr 1:

With Query3 Do
Begin
  Close;
  With SQL Do
  Begin
    Clear;
    Add('Select IVISBLU.CODITEM From IVISBLU ORDER BY CODITEM');
  end;
  OPEN;
  Table2CODITEM.Value := Query3CodITEM.AsInteger +1;
end;
para isto basta que você obtenha o maior valor para aquele header:
With Query3 Do
Begin
  Close;
  With SQL Do
  Begin
    Clear;
    Add('Select MAX(CODITEM) From IVISBLU where CODIGO = :CODIGO');
  end;
  ParamByName('CODIGO').AsInteger := Table1Codigo.Value;
  Open;
  Table2CODITEM.Value := Query3CodITEM.AsInteger +1;
end;

voce estará obtendo o valor máximo para o CODIGO tal...

Abraços

p.s. lembra o que eu disse antes, pode retirar o order by para este tipo de consulta.

Link to comment
Share on other sites

  • 0
para isto basta que você obtenha o maior valor para aquele header:

With Query3 Do

Begin

Close;

With SQL Do

Begin

Clear;

Add('Select MAX(CODITEM) From IVISBLU where CODIGO = :CODIGO');

end;

ParamByName('CODIGO').AsInteger := Table1Codigo.Value;

Open;

Table2CODITEM.Value := Query3CodITEM.AsInteger +1;

end;

voce estará obtendo o valor máximo para o CODIGO tal...

R. Carinha tem certeza que é assim??

ta dando erro:

[Error] LCVisita.pas(528): Incompatible types: 'Integer' and 'Double'

nesta linha:

ParamByName('CODIGO').AsInteger := Table1Codigo.Value;

Pra ter uma ideia Na DbGrid eu deveria ver assim:
No dbgrid da detalhes aparece assim(note que a cada mudança da master o coditem vira e começa a contar de novo:

CodMaster--coditem(contador)
       1              1
       1              2
       1              3
       2              1
       2              2
       3              1
       3              2
       3              3
e assim por diante(acho que você irá entender).

p.s. lembra o que eu disse antes, pode retirar o order by para este tipo de consulta.

R. Opa...já retirei... ;)

T+..valeu....abraço

Link to comment
Share on other sites

  • 0

Oba...Micheus.

Este codigo abaixo não consegui pegar a ideia...acho que você se confundiu um pouco:

With Query3 Do
Begin
Close;
With SQL Do
Begin
Clear;
Add('Select MAX(CODITEM) From IVISBLU where CODIGO = :CODIGO');
end;
ParamByName('CODIGO').AsInteger := Table1Codigo.Value;
Open;
Table2CODITEM.Value := Query3CodITEM.AsInteger +1;
end;
Esta linha aqui: Add('Select MAX(CODITEM) From IVISBLU where CODIGO = :CODIGO'); tudo bem...o CODITEM é o codigo da IVISBLU e este CODIGO é o parametro....mas o outro CODIGO da onde você pegou...eu não o tenho na tabela IVISBLU?? Esta Linha aqui:
ParamByName('CODIGO').AsInteger := Table1Codigo.Value;

belza..o CODIGO é o parametro.....E ai ele pega o codigo da tabela1??

o resto ok... ;)

Só poderias explicar estes detalhes porque empaquei.....

estrutura das duas tabelas:

MASTER(VISBLU)TABLE1:

CODIGO

DETALHES(IVISBLU)TABLE2:

CODVISITA

CODITEM

o relacionamento é entre o (VISBLU.CODIGO = IVISBLU.CODVISITA)

É o TABLE2.IVISBLU.CODITEM que to tendo dificuldades em contar e zerar a cada mudança do TABLE1.VISBLU.CODIGO

( a consulta estou fazendo em cima de uma query3).

Espero ter explicado...a real situação.

valeu..carinha.

Bom Dia de Trabalho.

Abraço

t+ :D

Link to comment
Share on other sites

  • 0
Este codigo abaixo não consegui pegar a ideia...acho que você se confundiu um pouco:

Esta linha aqui:

Add('Select MAX(CODITEM) From IVISBLU where CODIGO = :CODIGO');

tudo bem...o CODITEM é o codigo da IVISBLU e este CODIGO é o parametro....mas o outro CODIGO da onde você pegou...eu não o tenho na tabela IVISBLU??

Esta Linha aqui:

ParamByName('CODIGO').AsInteger := Table1Codigo.Value;

belza..o CODIGO é o parametro.....E ai ele pega o codigo da tabela1??

Só poderias explicar estes detalhes porque empaquei.....

estrutura das duas tabelas:

MASTER(VISBLU)TABLE1:

CODIGO

DETALHES(IVISBLU)TABLE2:

CODVISITA

CODITEM

o relacionamento é entre o (VISBLU.CODIGO = IVISBLU.CODVISITA)

É o TABLE2.IVISBLU.CODITEM que to tendo dificuldades em contar e zerar a cada mudança do TABLE1.VISBLU.CODIGO

( a consulta estou fazendo em cima de uma query3).

C's querem me quebrar mesmo :D

Sempre que aparece uma pergunta deste tipo, e não tenho a estrutura da tabela, eu sempre parto do princípio que o campo chave da tabela pai é duplicada na tabela filho. Logo, quando me referi a CODIGO você deveria ter entendido CODVISITA. Assim:

Add('Select MAX(CODITEM) From IVISBLU where CODIGO = :CODIGO');

ParamByName('CODIGO').AsInteger := Table1Codigo.Value;

passa a ser:

Add('Select MAX(CODITEM) From IVISBLU where CODVISITA = :CODVISITA');

ParamByName('CODVISITA').AsInteger := Table1Codigo.Value;

A hora que eu conseguir ler pensamentos este tipo de problema acaba mas, apesar de tentar, tá difícil. ;)

Abraços

Link to comment
Share on other sites

  • 0
C's querem me quebrar mesmo

Sempre que aparece uma pergunta deste tipo, e não tenho a estrutura da tabela, eu sempre parto do princípio que o campo chave da tabela pai é duplicada na tabela filho. Logo, quando me referi a CODIGO você deveria ter entendido CODVISITA. Assim:

Add('Select MAX(CODITEM) From IVISBLU where CODIGO = :CODIGO');

ParamByName('CODIGO').AsInteger := Table1Codigo.Value;

passa a ser:

Add('Select MAX(CODITEM) From IVISBLU where CODVISITA = :CODVISITA');

ParamByName('CODVISITA').AsInteger := Table1Codigo.Value;

A hora que eu conseguir ler pensamentos este tipo de problema acaba mas, apesar de tentar, tá difícil.

R. Ok..Micheus....eu perto do meio dia tinha me deparado com a interpretação, mas não respondi antes porque esta muito ocupado.

Mas...beleza...Perdão.

Micheus...deu um errinho nesta linha:

ParamByName('CODVISITA').AsInteger := Table1Codigo.Value;
[Error] LCVisita.pas(547): Incompatible types: 'Integer' and 'Double' tentei mudar assim:
ParamByName('CODVISITA').AsInteger := Table1Codigo.AsInteger;

ai o erro não apareceu...mas na hora de gravar na tabela..ai deu erro de argumento.

muito Grato..pela paciência. :unsure:

Link to comment
Share on other sites

  • 0
R. Ok..Micheus....eu perto do meio dia tinha me deparado com a interpretação, mas não respondi antes porque esta muito ocupado.

Mas...beleza...Perdão.

calma não é para tanto :D

Micheus...deu um errinho nesta linha:

ParamByName('CODVISITA').AsInteger := Table1Codigo.Value;
[Error] LCVisita.pas(547): Incompatible types: 'Integer' and 'Double' tentei mudar assim:
ParamByName('CODVISITA').AsInteger := Table1Codigo.AsInteger;
ai o erro não apareceu...mas na hora de gravar na tabela..ai deu erro de argumento.
Eder, desta vez você passou perto... Ao que me parece se campo de código está definido como NUMERIC e não INTEGER, então deveria ter trocado por:
ParamByName('CODVISITA').AsFloat := Table1Codigo.Value;

Abraços

Link to comment
Share on other sites

  • 0

Eder, desta vez você passou perto...
Ao que me parece se campo de código está definido como NUMERIC e não INTEGER, então deveria ter trocado por:

ParamByName('CODVISITA').AsFloat := Table1Codigo.Value;

R. Sim é numérico....troquei ...compilou mas deu erro ...acho que é erro da Query3...parece que não ta aceitando o select.

Erro: Project xxxx.exe Raised exception class econvertError With Message 'Nenhum argumento pra o formato '%s"

Olhei os parametros da Query3...mas o seu select já coloca o parametro em tempo de execução..

Tem algo em Especial na configuração do componente TQuery??

Grato

Link to comment
Share on other sites

  • 0

Eder, conferindo...

Sua query3 está deste jeito agora?

With Query3 Do
Begin
  Close;
  With SQL Do
  Begin
    Clear;
    Add('Select MAX(CODITEM) From IVISBLU where CODIGO = :CODIGO');
  end;
  ParamByName('CODVISITA').AsFloat := Table1Codigo.Value;
  Open;
  Table2CODITEM.Value := Query3CodITEM.AsInteger +1;
end;

Em que linha o erro está ocorrendo? No momento do Open ou na atribuição "Table2CODITEM.Value := Query3CodITEM.AsInteger +1;"?

Pela mensagem é como se você (ou o componente internamente) estivesse utilizando alguma formatação de campo. Esse "%s" é usado com a função Format, e aparentemente em algum momento esta conversão parece estar sendo feita, porêm não estaria sendo informado um dos parâmetros esperados (neste caso uma string).

Link to comment
Share on other sites

  • 0

Oba...

Eder, conferindo...

Sua query3 está deste jeito agora?

CODE

With Query3 Do

Begin

Close;

With SQL Do

Begin

Clear;

Add('Select MAX(CODITEM) From IVISBLU where CODIGO = :CODIGO');

end;

ParamByName('CODVISITA').AsFloat := Table1Codigo.Value;

Open;

Table2CODITEM.Value := Query3CodITEM.AsInteger +1;

end;

R. Não esta assim:

With Query3 Do
Begin
Close;
With SQL Do
Begin
Clear;
Add('Select MAX(CODITEM) From IVISBLU where CODVISITA = :CODVISITA');
end;
ParamByName('CODVISITA').AsFloat := Table1Codigo.Value;
Open;
Table2CODITEM.Value := Query3CODITEM.AsInteger +1;
end;
Em que linha o erro está ocorrendo? No momento do Open ou na atribuição "Table2CODITEM.Value := Query3CodITEM.AsInteger +1;"?
Fiz pela sequencia...e o erro apareceu no:
Open;

Pela mensagem é como se você (ou o componente internamente) estivesse utilizando alguma formatação de campo. Esse "%s" é usado com a função Format, e aparentemente em algum momento esta conversão parece estar sendo feita, porêm não estaria sendo informado um dos parâmetros esperados (neste caso uma string).

R. Esta mensagem do delphi 4 e meio mentirosa..pois uma vez um colega do forum teve uma interpretação parecida com a sua...num erro igual a este...

Eu verifiquei na query3 e não tem nada como você mencionou acima..esta query estou usando exclusivamente pra esta consulta. :(

Valeu...Grato..t+

Link to comment
Share on other sites

  • 0

Eder, é foi barberagem minha mesmo. É claro que o código tem que estar deste jeito.

Parece que você teria, na Query3, adicionado o SQL e também os fields da mesma em design-time. Pelo menos é o que parece pelo nome do componente Query3CODITEM.

Se isto é verdade, então você não precisa mudar a propriedade SQL em run-time e pode definir na propriedade Params, o tipo de dado que deve ser o parâmetro passado (no seu caso um NUMERIC, ou seja Float). Dê uma verificada.

Faça um teste. Execute esta query no Database Desktop. Dê um código conhecido ao parâmetro e execute a query.

Se você não obter o erro, então, vai ter que estar no componente.

já está começando a faltar idéias.. :)

Link to comment
Share on other sites

  • 0
Parece que você teria, na Query3, adicionado o SQL e também os fields da mesma em design-time. Pelo menos é o que parece pelo nome do componente Query3CODITEM.

Se isto é verdade, então você não precisa mudar a propriedade SQL em run-time e pode definir na propriedade Params, o tipo de dado que deve ser o parâmetro passado (no seu caso um NUMERIC, ou seja Float). Dê uma verificada.

R...sim fiz em Desing-Time

TA ASSIM configurado na query=sql=items=Select MAX(CODITEM) From IVISBLU where CODVISITA = :CODVISITA

e nos (TParams) da propria query coloquei:codvisita datatype=ftfloat

e no Table2BeforePost só ficou este codigo:

Table2CODITEM.Value := Query3CODITEM.AsInteger +1;

Ai testei...o primeito registro da Detalhes até da certo, mas apartir do primeiro(1) ai começa dar erro de KeyViolation :(

Carinha já to quase desistindo......e dando um tempo...hehehe

pergunto a você...to vendo que ta complicado resolver esta pepa...até você diz que já ta faltando ideias...hehehe...então eu te pergunto....isto tudo porque o campo é numerico certo??....e se fosse autoincremento...acho que ai não daria problema né, pois ele incremente sempre no POST né??

E pra converter estes dados de numerico pra autoincremento...daria?? ai resolveria esta pepa.

Tentei fazer isto no database desktop mas ele não me deixa...converter. :(

O que acha??? é que preciso colocar este codigo em operação entende....e não estou conseguindo.

Bom é isto....carinha...fazer o que...tamos tentando..

valeu..

Link to comment
Share on other sites

  • 0
TA ASSIM configurado na query=sql=items=Select MAX(CODITEM) From IVISBLU where CODVISITA = :CODVISITA

e nos (TParams) da propria query coloquei:codvisita datatype=ftfloat

e no Table2BeforePost só ficou este codigo:

Table2CODITEM.Value := Query3CODITEM.AsInteger +1;

acho que você deveria utilizar Query3CODITEM.AsFloat, já que está tratando de numéric, ok!?

Ai testei...o primeito registro da Detalhes até da certo, mas apartir do primeiro(1) ai começa dar erro de KeyViolation :(
isto é novo!!!

Voce conferiu se:

- está inicializando Table2CODVISITA.Value := Table1CODIGO.Value em cada Insert/Append na Table2?

- ao executar a busca pelo novo valor (Query3), o registro da tabela detalhe já está gravado?

Carinha já to quase desistindo......e dando um tempo...hehehe

e se fosse autoincremento...acho que ai não daria problema né, pois ele incremente sempre no POST né??
e você não calcula ele no BeforePost? (deveria ser)

E pra converter estes dados de numerico pra autoincremento...daria?? ai resolveria esta pepa.

Tentei fazer isto no database desktop mas ele não me deixa...converter. :(

é eu acho que teria que criar um campo intermediário (inteiro), mover apenas a parte inteira para ele, dropar a coluna numeric, criá-la novamente como integer, mover a coluna temporária para a nova e transformá-la em autoincremente (mais ou menos tudo isso)

Independente disto, é recomendado que você não utilize campos numeric para a finalidade aque exposta (código sequencial de controle)

Link to comment
Share on other sites

  • 0
TA ASSIM configurado na query=sql=items=Select MAX(CODITEM) From IVISBLU where CODVISITA = :CODVISITA

e nos (TParams) da propria query coloquei:codvisita datatype=ftfloat

e no Table2BeforePost só ficou este codigo:

Table2CODITEM.Value := Query3CODITEM.AsInteger +1;

acho que você deveria utilizar Query3CODITEM.AsFloat, já que está tratando de numéric, ok

R. Ok....substitui

começa dar erro de KeyViolation

isto é novo!!!

Voce conferiu se:

- está inicializando Table2CODVISITA.Value := Table1CODIGO.Value em cada Insert/Append na Table2?

- ao executar a busca pelo novo valor (Query3), o registro da tabela detalhe já está gravado

R. Sim tudo certinho.

Carinha eu fiz um testezinho e reparei que a query3 não me traz resultado algum...ou seja nada...pois quanto tento gravar o primeiro registro da detalhes não da erro..pois como esta somando o + 1(mas 1) ela grava normalmente..ai explica quando vou pro segundo e da erro de KeyViolation...pois ela torna a querer gravar o 1 de novo...porque a query3 na me traz a qtidade de registros gravados...a consulta da query não funca.

:(

Então acho que o codigo na propria query3 com o parametro codvisita não funciona...é ali que acho que ta o erro..apartir do momento que a query3 me trazer o resultados da quantidade registros gravados ai funcionará certinho.

O que você acha?? :rolleyes:

E pra converter estes dados de numerico pra autoincremento...daria?? ai resolveria esta pepa.
Tentei fazer isto no database desktop mas ele não me deixa...converter. 
é eu acho que teria que criar um campo intermediário (inteiro), mover apenas a parte inteira para ele, dropar a coluna numeric, criá-la novamente como integer, mover a coluna temporária para a nova e transformá-la em autoincremente (mais ou menos tudo isso)
Independente disto, é recomendado que você não utilize campos numeric para a finalidade aque exposta (código sequencial de controle)

R. Este nem vou tentar de emediato....só vou tentar a hora que eu ver que não tem mais jeito da maneira que estamos discutindo acima ;) ....beleza?? :)

Abraço e bom final de semana...

t+

Edited by Eder
Link to comment
Share on other sites

  • 0
Carinha eu fiz um testezinho e reparei que a query3 não me traz resultado algum...ou seja nada...pois quanto tento gravar o primeiro registro da detalhes não da erro..pois como esta somando o + 1(mas 1) ela grava normalmente..ai explica quando vou pro segundo e da erro de KeyViolation...pois ela torna a querer gravar o 1 de novo...porque a query3 na me traz a qtidade de registros gravados...a consulta da query não funca.

:(

Então acho que o codigo na propria query3 com o parametro codvisita não funciona...é ali que acho que ta o erro..apartir do momento que a query3 me trazer o resultados da quantidade registros gravados ai funcionará certinho.

Foi por isso que perguntei:

Voce conferiu se:

- está inicializando Table2CODVISITA.Value := Table1CODIGO.Value em cada Insert/Append na Table2?

- ao executar a busca pelo novo valor (Query3), o registro da tabela detalhe já está gravado?

Parece que o campo código não está sendo gravado na sua tabela item, dai a cada busca pelo código da tabela mestre, nunca encontra ele e obtém o valor 1 para o item - grava então: Codigo = 0 e Item = 1; o que vai resultar em key violation a qualquer nova inclusão, mesmo de outro item para um segunto registro na tabela principal.

Na verdade, este cenário só vai acontecer se o campo código na tabela detalhe não for obrigatório;

E é fácil de verificar: após incluir o primeiro item, ou você debuga e verifica o valor do código no momento em que vai gravar o item ou, após gravado o 1º item, abra o Database Desktop e verifique como estão os dados na tabela de itens.

Dê uma averiguada, porque aparentemente, pelo que está na consulta aqui, ela deveria estar funcionando - parece mesmo apenas o código estar ficando nulo ou algo parecido.

Só mais uma curiosidade:

se a consulta Query3 está "Select MAX(CODITEM) From IVISBLU where CODVISITA = :CODVISITA", como é que você tem um campo adicionado a query chamado Query3CODITEM?

Supostamente deveria ser algo como Query3MAXOFcodigo, já que você não declara um nome para a coluna, e neste caso, a consulta deveria estar "Select MAX(CODITEM) AS CODITEM From IVISBLU where CODVISITA = :CODVISITA"

Abraços

Link to comment
Share on other sites

  • 0
Parece que o campo código não está sendo gravado na sua tabela item, dai a cada busca pelo código da tabela mestre, nunca encontra ele e obtém o valor 1 para o item - grava então: Codigo = 0 e Item = 1; o que vai resultar em key violation a qualquer nova inclusão, mesmo de outro item para um segunto registro na tabela principal.

Na verdade, este cenário só vai acontecer se o campo código na tabela detalhe não for obrigatório;

E é fácil de verificar: após incluir o primeiro item, ou você debuga e verifica o valor do código no momento em que vai gravar o item ou, após gravado o 1º item, abra o Database Desktop e verifique como estão os dados na tabela de itens.

Dê uma averiguada, porque aparentemente, pelo que está na consulta aqui, ela deveria estar funcionando - parece mesmo apenas o código estar ficando nulo ou algo parecido.

R. sim...o primeiro grava certinho...nem preciso abrir o database desktop pois tenho o Dbgrid que me mostra exatamente o que vai acontecendo.

Como falei em tópico anterior..a consulta não me traz nada....só funciona o primeiro item na gravação...pois é + 1 e é esto hum que é gravado como primeiro registros..após sempre da erro de key..pois ele quer gravar um de novo...pois a consulta não traz nada.

Só mais uma curiosidade:

se a consulta Query3 está "Select MAX(CODITEM) From IVISBLU where CODVISITA = :CODVISITA", como é que você tem um campo adicionado a query chamado Query3CODITEM?

Supostamente deveria ser algo como Query3MAXOFcodigo, já que você não declara um nome para a coluna, e neste caso, a consulta deveria estar "Select MAX(CODITEM) AS CODITEM From IVISBLU where CODVISITA = :CODVISITA"

R. aqui eu pipoquei mesmo...eu incluia no braço o CODITEM NA QUERY3.....pois senão ele não me deixava compilar...mas ai mudei agora assim como você me pede:

Select MAX(CODITEM) AS CODITEM From IVISBLU where CODVISITA = :CODVISITA
Mas mesmo assim.....a consulta não continua me trazendo valor....Não sei porque..deveria trazer, pois concordo a select ta correta...fiz um testezinho coloquei um label e coloquei este codigo no botão:
label1.caption:=floattostr(Query3CODITEM.AsFloat + 1);

e nada...só me traz o resultado 1

Grato...t+

Abraços

Link to comment
Share on other sites

  • 0

Carinha..achei a solução....até por sinal muito fácil...e deu certo.

With Query3 Do
 Begin
 Close;
   With Sql do
   Begin
   Clear;
   Add('Select IVISBLU.CODITEM, IVISBLU.CODVISITA From IVISBLU ');
   Add('WHERE IVISBLU.CODVISITA ='+ QuotedStr(table1CODIGO.Text));
   Add('ORDER BY IVISBLU.CODVISITA');
   end;
   Open;
   Query3.LAST;
   Table2CODITEM.Value := Query3CODITEM.AsInteger +1;
   END;

Finalmente deu certo..na verdade a ideia principal é a sua...mas ai ao invés de comparar com a propria table2...fiz a comparaçao entre table1 e table2...ai fechou direitinho.

:D ;)

Carinha...muito Grato pela Ajuda e pela paciência...afinal foram mais de 20 partes este tópico..ufa...

Abraços

:D

Link to comment
Share on other sites

  • 0
Carinha..achei a solução....até por sinal muito fácil...e deu certo.

(...)

Finalmente deu certo..na verdade a ideia principal é a sua...mas ai ao invés de comparar com a propria table2...fiz a comparaçao entre table1 e table2...ai fechou direitinho.

Com certeza é uma solução, mas devo lhe deixar ciente de que não é a melhor. Sem dúvidas, utilizar a função MAX seria o ideal, porque a consulta roda no banco (apesar de você utilizar Paradox, mas fica o conceito para um banco de verdade). Da forma como ficou, está sujeito a um processamento/transito de dados maior que o necessário, já que haverá bufferização da consulta realizada e você irá mover-se para a última.

Faz o seguinte para diminuir este "problema": obtenha o resultado em ordem decrescente e daí você pega o primeiro registro (não tem que "ir" até o último):

With Query3 Do
Begin
   Close;
   With Sql do
   Begin
     Clear;
     Add('Select IVISBLU.CODITEM, IVISBLU.CODVISITA From IVISBLU ');
     Add('WHERE IVISBLU.CODVISITA ='+ QuotedStr(table1CODIGO.Text));
     Add('ORDER BY IVISBLU.CODVISITA DESC');  // *** OBSERVE o --> DESC
   end;
   Open;
   Table2CODITEM.Value := Query3CODITEM.AsInteger +1;
Ene;

Carinha...muito Grato pela Ajuda e pela paciência...afinal foram mais de 20 partes este tópico..ufa...
sem problemas, a idéia não é apenas resolver o problema (tipo faz assim...), mas também, explicar/tirar dúvidas (na medida do possível). Senão, como você vai resolver outro problema parecido. ;)

Abraços

Link to comment
Share on other sites

  • 0
QUOTE(Eder @ 13/08/2007 - 10:02)

Carinha..achei a solução....até por sinal muito fácil...e deu certo.

(...)

Finalmente deu certo..na verdade a ideia principal é a sua...mas ai ao invés de comparar com a propria table2...fiz a comparaçao entre table1 e table2...ai fechou direitinho.

Com certeza é uma solução, mas devo lhe deixar ciente de que não é a melhor. Sem dúvidas, utilizar a função MAX seria o ideal, porque a consulta roda no banco (apesar de você utilizar Paradox, mas fica o conceito para um banco de verdade). Da forma como ficou, está sujeito a um processamento/transito de dados maior que o necessário, já que haverá bufferização da consulta realizada e você irá mover-se para a última.

Faz o seguinte para diminuir este "problema": obtenha o resultado em ordem decrescente e daí você pega o primeiro registro (não tem que "ir" até o último):

Add('ORDER BY IVISBLU.CODVISITA DESC'); // *** OBSERVE o --> DESC

R. Oba...desculpe a demora em responder só agora vi que você havia respondido ;)

Entendi o que você mencionou..e já alterei também incluindo o DESC

Carinha...muito Grato pela Ajuda e pela paciência...afinal foram mais de 20 partes este tópico..ufa...

sem problemas, a idéia não é apenas resolver o problema (tipo faz assim...), mas também, explicar/tirar dúvidas (na medida do possível). Senão, como você vai resolver outro problema parecido.

R.: Jóia....valeu...é bom contar com pessoas dispostar a ajudar...

Abraços..t+:)

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Answer this question...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share



  • Forum Statistics

    • Total Topics
      150.2k
    • Total Posts
      647.5k
×
×
  • Create New...