Auto numeração via Código.
Tenho um campo código na tabela e quero inseri-lo via edit, mas sempre acrescentando+1. Sei que existe o generator(nunca usei), mas existe alguma maneira de implementa-lo(acrescentando+1) via código?
Se faço via beforPost acrescenta+2, no botão Npost do navigator então acusa a mensagem que o campo está vazio, enfim, é isso.
Quero jogar esse número do código depois do preenchimento do cadastro, estou pensando no uso em uma rede.
Se faço via beforPost acrescenta+2, no botão Npost do navigator então acusa a mensagem que o campo está vazio, enfim, é isso.
Quero jogar esse número do código depois do preenchimento do cadastro, estou pensando no uso em uma rede.
Amilton/pr
Curtidas 0
Respostas
Afarias
11/12/2003
crie um generator no banco::
CREATE GENERATOR nome_generator;
crie a seginte ´função´ no delphi::
vc pode substituir o IBSQL por outro componente q esteja usando (que execute SQLs no IB)
vc pode usar o seginte código para pegar um novo código (no BeforePost ou OnNewRecord do seu DataSet)::
se tiver problemas com ´campo está vazio´ ... defina a propriedade REQUIRED do TField que representa o campo Código para FALSE.
T+
CREATE GENERATOR nome_generator;
crie a seginte ´função´ no delphi::
function TFormx.GetNewID(const AGenerator: string): Integer; const SQLText = ´select gen_id(¬s, 1) from rdb$database´; begin with IBSQL1 do begin SQL.Text := Format(SQLText, [AGenerator]); Transaction.StartTransaction; try ExecQuery; Result := Fields[0].AsInteger; finally Transaction.Commit; end; end; end;
vc pode substituir o IBSQL por outro componente q esteja usando (que execute SQLs no IB)
vc pode usar o seginte código para pegar um novo código (no BeforePost ou OnNewRecord do seu DataSet)::
SeuDataSet.FieldByName(´CODIGO´).AsInteger := GetNewID(´nome_generator´);
se tiver problemas com ´campo está vazio´ ... defina a propriedade REQUIRED do TField que representa o campo Código para FALSE.
T+
GOSTEI 0
Amilton/pr
11/12/2003
Blz., mas posso usar esse código no Botão nPost do Navigator ou tenho que colocar um botão pra gravar?
GOSTEI 0
Afarias
11/12/2003
Vc pode colocar onde quizer! Mas, é bom colocar as coisas no seu devido lugar ... sendo assim, aconselho q coloque o código nos eventos BeforePost ou OnNewRecord do DataSet.
Mas, como disse, vc pode colocar onde quizer.
T+
PS:: No caso de colocar no BeforePost, vc teria q antes ´perguntar´
if DataSet.State = dsInsert then
{...}
Mas, como disse, vc pode colocar onde quizer.
T+
PS:: No caso de colocar no BeforePost, vc teria q antes ´perguntar´
if DataSet.State = dsInsert then
{...}
GOSTEI 0
Amilton/pr
11/12/2003
Nessa Gerator . . .
1-function TFormx.GetNewID(const AGenerator: string): Integer;
2-const
3- SQLText = ´select gen_id(¬s, 1) from rdb$database´;
4-begin
5- with IBSQL1 do
6- begin
7- SQL.Text := Format(SQLText, [AGenerator]);
8- Transaction.StartTransaction;
9- try
10- ExecQuery;
11- Result := Fields[0].AsInteger;
12- finally
13- Transaction.Commit;
14- end;
15- end;
16-end;
Fiz uma numeração de linhas pra mostrar que dá erro na linha 7(acho que o ponto, mas tirei esse ponto e mesmo assim dá erro) e depois na linha 10.
1-function TFormx.GetNewID(const AGenerator: string): Integer;
2-const
3- SQLText = ´select gen_id(¬s, 1) from rdb$database´;
4-begin
5- with IBSQL1 do
6- begin
7- SQL.Text := Format(SQLText, [AGenerator]);
8- Transaction.StartTransaction;
9- try
10- ExecQuery;
11- Result := Fields[0].AsInteger;
12- finally
13- Transaction.Commit;
14- end;
15- end;
16-end;
Fiz uma numeração de linhas pra mostrar que dá erro na linha 7(acho que o ponto, mas tirei esse ponto e mesmo assim dá erro) e depois na linha 10.
GOSTEI 0
Afarias
11/12/2003
Bom, não sei se já te falei: procure manter cada dicussão no seu lugar ok? Especificamente esta, vamos manter e continuar apenas aqui certo??
Bom, não há erros neste procedimento, então::
Qual a mensagem de erro q vc está recebendo??
T+
Bom, não há erros neste procedimento, então::
Qual a mensagem de erro q vc está recebendo??
T+
GOSTEI 0
Amilton/pr
11/12/2003
Muito bem, meu amigo!!!!
Olha, criei um Generator com o nome de P_Gener, com o valor 0.
Na função na linha:
SQLText := Format(SQLText, [AGenerator]);
Obs. na instrução está sql.text, aqui é sqltext, sem o ponto. Com o ponto dá a mensagem : undeclared Identifier SQL.
mensagem de erro nessa instrução: left side cannot be assigned to
Aguaro retorno . . .
Olha, criei um Generator com o nome de P_Gener, com o valor 0.
Na função na linha:
SQLText := Format(SQLText, [AGenerator]);
Obs. na instrução está sql.text, aqui é sqltext, sem o ponto. Com o ponto dá a mensagem : undeclared Identifier SQL.
mensagem de erro nessa instrução: left side cannot be assigned to
Aguaro retorno . . .
GOSTEI 0
Amilton/pr
11/12/2003
Ainda sobre o Generator na linha ExecQuery;
Essa mensagem: Undeclared Identifier ´ExecQuery´
Para complementar sobre o Generator em questão . . .
Essa mensagem: Undeclared Identifier ´ExecQuery´
Para complementar sobre o Generator em questão . . .
GOSTEI 0
Afarias
11/12/2003
|criei um Generator com o nome de P_Gener, com o valor 0.
|Na função na linha: SQLText := Format(SQLText, [AGenerator]);
NÃO É SQLText := {...} é ::: SQL.Text := {...}
TEM o PONTO ok?! SQL é uma propriedade do IBSQL que é do tipo TStrings. E Text é uma propriedade do TStrings.
Depois no Format, tem SQLText (sem ponto) que, se vc reparar é o nome da constante criada!! (Vc pode renomear a constante para outro nome q mais lhe agradar)
Vc usaria a função da forma (EX.)::
MinhaVariavel := GetNewID(´P_GENER´);
|Obs. na instrução está sql.text, aqui é sqltext, sem o ponto. Com o ponto
|dá a mensagem : undeclared Identifier SQL.
É pq vc provavelmente não está usando um IBSQL. Se vc está usando outro componente, tem q mudar algumas coisas no código para este componente específico.
|Ainda sobre o Generator na linha ExecQuery;
|Essa mensagem: Undeclared Identifier ´ExecQuery´
Mesma coisa!
T+
|Na função na linha: SQLText := Format(SQLText, [AGenerator]);
NÃO É SQLText := {...} é ::: SQL.Text := {...}
TEM o PONTO ok?! SQL é uma propriedade do IBSQL que é do tipo TStrings. E Text é uma propriedade do TStrings.
Depois no Format, tem SQLText (sem ponto) que, se vc reparar é o nome da constante criada!! (Vc pode renomear a constante para outro nome q mais lhe agradar)
Vc usaria a função da forma (EX.)::
MinhaVariavel := GetNewID(´P_GENER´);
|Obs. na instrução está sql.text, aqui é sqltext, sem o ponto. Com o ponto
|dá a mensagem : undeclared Identifier SQL.
É pq vc provavelmente não está usando um IBSQL. Se vc está usando outro componente, tem q mudar algumas coisas no código para este componente específico.
|Ainda sobre o Generator na linha ExecQuery;
|Essa mensagem: Undeclared Identifier ´ExecQuery´
Mesma coisa!
T+
GOSTEI 0
Amilton/pr
11/12/2003
Legal!
Realmente . . . estou usando o componente IbDataset e ele não tem a propriedade SQL, mas substitui pelo comando SelectSql.text e não deu o erro mais. Agora na linha ExecQuery continua com a mesma situação.
Tem algum comando para executar um IbDataset como um IbQuery pra resolvermos isso?
Realmente . . . estou usando o componente IbDataset e ele não tem a propriedade SQL, mas substitui pelo comando SelectSql.text e não deu o erro mais. Agora na linha ExecQuery continua com a mesma situação.
Tem algum comando para executar um IbDataset como um IbQuery pra resolvermos isso?
GOSTEI 0
Afarias
11/12/2003
Já q vc está usando IBX, não é mais fácil vc simplesmente usar um IBSQL no lugar do IBDataSet?? Cada coisa no seu lugar -- o IBDataSet não é feito pra isso, o IBSQL sim.
T+
T+
GOSTEI 0
Amilton/pr
11/12/2003
Posso perfeitamente fazer isso, na verdade eu não sei exatamente como funciona e nem as diferenças entre ambos, mas no caso da IbQuery como fica alterar, incluir, deletar, enfim . . . a manutenção em geral se não tem as propriedades InsertSql, DeleteSql, etc?
Poderia me dizer as diferenças e funções desses componentes?
Poderia me dizer as diferenças e funções desses componentes?
GOSTEI 0
Afarias
11/12/2003
Veja Amilton,
Para selecionar os registros e editá-los, vc deve usar um IBDataSet Ok??
Se vc quer gerar o código automático direto no IBDataSet, vc pode usar a propriedade GeneratorField para isso Ok??
Bom, como vc quer gerar o valor via código... vc deve usar uma função como aquela -- é algo a parte -- não tem nada a ver com a seleção e edição de registros!!!! É só pra gerar um novo código em qualquer parte q vc desejar certo???
E eu não disse IBQuery eu disse IBSQL, os componentes IBX são divididos mais ou menos assim::
IBTable - não serve pra nada
IBStoredProc - procedimentos ´executáveis´ (os ´selecionáveis´ não)
IBQuery - seleção de registros (e alteração caso usado em conjunto com um IBUpdateSQL)
IBDataSet - é igual a 1 IBQuery + 1 IBUpdateSQL
IBSQL - executar comandos SQL (inclusive consultas -- unidirecional e sem suporte a controles visuais)
T+
Para selecionar os registros e editá-los, vc deve usar um IBDataSet Ok??
Se vc quer gerar o código automático direto no IBDataSet, vc pode usar a propriedade GeneratorField para isso Ok??
Bom, como vc quer gerar o valor via código... vc deve usar uma função como aquela -- é algo a parte -- não tem nada a ver com a seleção e edição de registros!!!! É só pra gerar um novo código em qualquer parte q vc desejar certo???
E eu não disse IBQuery eu disse IBSQL, os componentes IBX são divididos mais ou menos assim::
IBTable - não serve pra nada
IBStoredProc - procedimentos ´executáveis´ (os ´selecionáveis´ não)
IBQuery - seleção de registros (e alteração caso usado em conjunto com um IBUpdateSQL)
IBDataSet - é igual a 1 IBQuery + 1 IBUpdateSQL
IBSQL - executar comandos SQL (inclusive consultas -- unidirecional e sem suporte a controles visuais)
T+
GOSTEI 0
Amilton/pr
11/12/2003
Desculpe, disse IbQuery mas colei o componente IbSql.
Olha, usei a propriedade GeneratorField para incrmentar o código em 1, no Dataset, assim: Nome da Generetor: P_Gener - Obs. Mudei o valor da Generator para 0;
Field: Codigo
Increment: 1
Apply event: opcao New Record -
Quando rodo o programa dá violação de chave.
Olha, usei a propriedade GeneratorField para incrmentar o código em 1, no Dataset, assim: Nome da Generetor: P_Gener - Obs. Mudei o valor da Generator para 0;
Field: Codigo
Increment: 1
Apply event: opcao New Record -
Quando rodo o programa dá violação de chave.
GOSTEI 0
Afarias
11/12/2003
vc não pode voltar o valor de um generator q está sendo usado se já existem registros na tabela a qual ele se presta. o q vc vai ter é violações de chave primária.
T+
T+
GOSTEI 0
Amilton/pr
11/12/2003
Blz. Limpei a tabela e comecei a inserir os dados.
Coloquei o valor da Generator em 0 ou 1, isso incluencia em algo?
Na propriedade GeneratorField na opção ApplyField marquei OnPost e LEGAL!!! agora está funcionando Blz.
Depois de tudo, aparente simples, né?
Pelo que entendi esse código gerado é autoincremento, só conseguirei a editar registros do inicio se limpar a tabela e começar tudo novamente?
Em que situação, então eu usaria o Generator com IbSql?
Coloquei o valor da Generator em 0 ou 1, isso incluencia em algo?
Na propriedade GeneratorField na opção ApplyField marquei OnPost e LEGAL!!! agora está funcionando Blz.
Depois de tudo, aparente simples, né?
Pelo que entendi esse código gerado é autoincremento, só conseguirei a editar registros do inicio se limpar a tabela e começar tudo novamente?
Em que situação, então eu usaria o Generator com IbSql?
GOSTEI 0
Afarias
11/12/2003
|Coloquei o valor da Generator em 0 ou 1, isso incluencia em algo?
Não
|Depois de tudo, aparente simples, né?
é! :D
|Pelo que entendi esse código gerado é autoincremento, só conseguirei a
|editar registros do inicio se limpar a tabela e começar tudo novamente?
é... vc não pode ficar voltando os valores. não se preocupe com isso, a única função de um código é ser ÚNICO e não ser sequencial (sem buracos).
|Em que situação, então eu usaria o Generator com IbSql?
Várias... quando não se deseja usar a propriedade GeneratorField por algum motivo particular, quando vc não usa IBX (não seria então com IBSQL mas com outro componente com a mesma função), quando se usa MIDAS, etc... (quem manda é o cliente! ;))
T+
Não
|Depois de tudo, aparente simples, né?
é! :D
|Pelo que entendi esse código gerado é autoincremento, só conseguirei a
|editar registros do inicio se limpar a tabela e começar tudo novamente?
é... vc não pode ficar voltando os valores. não se preocupe com isso, a única função de um código é ser ÚNICO e não ser sequencial (sem buracos).
|Em que situação, então eu usaria o Generator com IbSql?
Várias... quando não se deseja usar a propriedade GeneratorField por algum motivo particular, quando vc não usa IBX (não seria então com IBSQL mas com outro componente com a mesma função), quando se usa MIDAS, etc... (quem manda é o cliente! ;))
T+
GOSTEI 0
Marshall Mathers
11/12/2003
afarias, e se meu campo for chave primária?!??! naum dá pra definir chave primária sem ser not null.... como eu faço entaum?
GOSTEI 0
Afarias
11/12/2003
é, chave primária não pode ter NULOS, mas não entendi o q vc quer.
Exclareça melhor sua dúvida.
T+
Exclareça melhor sua dúvida.
T+
GOSTEI 0
Amilton/pr
11/12/2003
Cara, isso é muito bom. Ficou legal.
Em tabelas Firebird quando se cria um segundo índice(seria um indice secundário, como no Paradox?), como se faz para mudar o indice e usa-lo?, ou via SQL usa-se indice por Order by?
Um abraço!
Em tabelas Firebird quando se cria um segundo índice(seria um indice secundário, como no Paradox?), como se faz para mudar o indice e usa-lo?, ou via SQL usa-se indice por Order by?
Um abraço!
GOSTEI 0
Amilton/pr
11/12/2003
Essa rotina de incremento funciona bem em rede?
GOSTEI 0
Marshall Mathers
11/12/2003
é, chave primária não pode ter NULOS, mas não entendi o q vc quer.
Exclareça melhor sua dúvida.
T+
Pq o registro naum vai salvar se o edit estiver em branco. Ele vai dar erro na chave primária que não pode ser nula, sakou?
GOSTEI 0
Marshall Mathers
11/12/2003
Uma pergunta rápida.... eu tenho um campo que criei com um DOMAIN para ser booleano, e ae estou usando ele no delphi com CheckBoxes, mas só que na hora em que eu vou salvar um registro em que eu num marquei o checkbox ele dá a seguinte msg:
1ª) Project SysInvent.exe raised exception class EIBInterbaseError with message ´validation error for column CxSom, value ´***null***´. Process stoped, bla,bla,bla......
2ª) validation error for column CxSom, value ´***null***´.
Eu usei o seguinte código para fazer o DOMAIN:
CREATE DOMAIN DM_LOGICO2 AS
CHAR(1) CHARACTER SET WIN1252
DEFAULT ´N´
CHECK ((VALUE IN (´S´,´N´)))
COLLATE PXW_INTL850
E ae, vc pode me ajudar a resolver... só falta isso....
De qualquer forma valeus.....
1ª) Project SysInvent.exe raised exception class EIBInterbaseError with message ´validation error for column CxSom, value ´***null***´. Process stoped, bla,bla,bla......
2ª) validation error for column CxSom, value ´***null***´.
Eu usei o seguinte código para fazer o DOMAIN:
CREATE DOMAIN DM_LOGICO2 AS
CHAR(1) CHARACTER SET WIN1252
DEFAULT ´N´
CHECK ((VALUE IN (´S´,´N´)))
COLLATE PXW_INTL850
E ae, vc pode me ajudar a resolver... só falta isso....
De qualquer forma valeus.....
GOSTEI 0
Marshall Mathers
11/12/2003
Alguém pod me ajudar ae????
GOSTEI 0
Afarias
11/12/2003
Vamos por partes....
Amilton/Pr::
|Essa rotina de incremento funciona bem em rede?
Que rotina? A que te passei?? SIM!
|Em tabelas Firebird quando se cria um segundo índice(seria um indice
|secundário, como no Paradox?), como se faz para mudar o indice e usa-
|lo?, ou via SQL usa-se indice por Order by?
Vc apebas cria os índices quem usa é o servidor. Não se preocupe com eles.
Marshall Mathers::
|Pq o registro naum vai salvar se o edit estiver em branco. Ele vai dar
|erro na chave primária que não pode ser nula, sakou?
Coloque o TField em questão como Required=False
|eu tenho um campo que criei com um DOMAIN para ser booleano, e ae
|estou usando ele no delphi com CheckBoxes, mas só que na hora em
| {...}
seu domain não permite NULOS, sendo assim, faça com q seu código sempre jogue apenas ´S´ ou ´N´ no campo
T+
Amilton/Pr::
|Essa rotina de incremento funciona bem em rede?
Que rotina? A que te passei?? SIM!
|Em tabelas Firebird quando se cria um segundo índice(seria um indice
|secundário, como no Paradox?), como se faz para mudar o indice e usa-
|lo?, ou via SQL usa-se indice por Order by?
Vc apebas cria os índices quem usa é o servidor. Não se preocupe com eles.
Marshall Mathers::
|Pq o registro naum vai salvar se o edit estiver em branco. Ele vai dar
|erro na chave primária que não pode ser nula, sakou?
Coloque o TField em questão como Required=False
|eu tenho um campo que criei com um DOMAIN para ser booleano, e ae
|estou usando ele no delphi com CheckBoxes, mas só que na hora em
| {...}
seu domain não permite NULOS, sendo assim, faça com q seu código sempre jogue apenas ´S´ ou ´N´ no campo
T+
GOSTEI 0
Amilton/pr
11/12/2003
Preciso criar um Generator para cada tabela que queiro fazer um autoincremento ou posso usar o mesmo Generator para todas tabelas?
GOSTEI 0
Marshall Mathers
11/12/2003
|seu domain não permite NULOS, sendo assim, faça com q seu código
|sempre jogue apenas ´S´ ou ´N´ no campo
T+
[color=blue:3f1d612144]Se não for pedir muito, vc pode me dar um exemplo de um DOMAIN assim???[/color:3f1d612144]
GOSTEI 0
Afarias
11/12/2003
|Preciso criar um Generator para cada tabela que queiro fazer um
|autoincremento ou posso usar o mesmo Generator para todas tabelas?
Um pra cada CAMPO q receberá os valores (auto-numeração)
|Se não for pedir muito, vc pode me dar um exemplo de um DOMAIN
|assim???
Não entendi... o DOMAIN está correto, vc tem apenas q no código, sempre inserir um dos valores permitidos no domais, nunca inserir Nulos por exemplo. É isso?!
T+
|autoincremento ou posso usar o mesmo Generator para todas tabelas?
Um pra cada CAMPO q receberá os valores (auto-numeração)
|Se não for pedir muito, vc pode me dar um exemplo de um DOMAIN
|assim???
Não entendi... o DOMAIN está correto, vc tem apenas q no código, sempre inserir um dos valores permitidos no domais, nunca inserir Nulos por exemplo. É isso?!
T+
GOSTEI 0
Marshall Mathers
11/12/2003
Não entendi... [b:70e31086c1]o DOMAIN está correto, vc tem apenas q no código, sempre inserir um dos valores permitidos no domais, nunca inserir Nulos[/b:70e31086c1] por exemplo. É isso?!
Certo, mas eu não estou inserindo nulos.... eu fiz o meu campo no FB com esse código de DOMAIN, e ae quando chegou no Delphi eu coloquei CheckBoxes para representar esses campos, e nas propriedades ValueChecked eu coloquei = S e ValueUnchecked=N.... como está no DOMAIN, mas sempre que eu deixo um CheckBox desmarcado ele dá a mesma mensagem.... agora eu num tow intendendo nada..... por favor me ajude....
GOSTEI 0
Afarias
11/12/2003
Pq, quando o registro é ´criado´ inicialmente seu valor é NULL e no checkbox aparece desmarcado (se vc não usa aquela opção ´intermediária´) -- para resolver seu problema, apenas faça o seguinte, no evento OnNewRecord da Query/DataSet adicione::
DataSet.FieldByName(´CampoLigadoAoCheckBox´).AsString := ´N´;
T+
DataSet.FieldByName(´CampoLigadoAoCheckBox´).AsString := ´N´;
T+
GOSTEI 0
Marshall Mathers
11/12/2003
afarias, vc é o cara.... fucionou blz... ufa, posso até respirar melhor, pq meu chefe tava me argolando por causa desse prog e só faltava isso... vc salvou a minha pele... diz ae o q vc ker de natal... eu dou um toque pro bom velhinho te mandar ae.... heheheheh.... [color=red:9d787cf4f5][b:9d787cf4f5]MUITO OBRIGADO MESMO![/b:9d787cf4f5][/color:9d787cf4f5] :D :D :D :D :lol: :lol: :lol: :lol:
GOSTEI 0