Generator doesn’t always increase +1 when searching for it, see the examples:
Here will be incremented +1 to Generator
SELECT GEN_ID(GENERATOR, 1) AS ID FROM RDB$DATABASE
Already this way below, only the current value of Generator is returned
SELECT GEN_ID(GENERATOR, 0) AS ID FROM RDB$DATABASE
I believe you can create a Rigger in your own order table and do the desired validation and restart the count of it.
Example - EDITED
I’m not sure how you do in your application, but I’ll give you another example and you try to apply, is another example using Rigger (I don’t know much about procedures)...
Note: I tested with Firedac and read in some places that Dbexpress
also works with returning
first - Create Trigger by applying the validations you use in the application:
CREATE TRIGGER PEDIDO_BI0 FOR PEDIDO
ACTIVE BEFORE INSERT POSITION 0
AS
begin
if ((SELECT GEN_ID(COD_PEDIDO, 0) AS ID FROM RDB$DATABASE) = 1000) then
EXECUTE STATEMENT('SET GENERATOR COD_PEDIDO TO 0');
new.PE_CODIGO = 'ABC' || (SELECT GEN_ID(COD_PEDIDO, 1) AS ID FROM RDB$DATABASE);
end
2nd - You said you use the order PK to form the order items PK, so try this way:
procedure MetodoInsertPedido;
begin
{Vai inserir o pedido, sem informar a PK, pois a trigger irá tratá-la e após a inserção o RETURNING da query irá retornar a PK gerada na trigger}
qryInsert.SQL.CommandText := 'insert into pedido(data, valor) values (current_date, 10.50) returning id';
qryInsert.Open; {Sim use o open}
{Aqui você pega o valor da PK que a trigger gerou}
IdPedido = qryInsert.FieldByName('id').AsString;
[...insert itens do pedido...]
end;
Understanding
1º - The Trigger will be fired before happen the insertion of the order in the table and then you can treat your PK directly on Trigger, passing to it the values you need
2º - When using the returning
and run the Insert using Open()
of the query things happened like this:
• Runs script from Insert
• Fires Trigger, which generates the id and already arrow it to the record
• After execution the id for the query is returned
You commented something about access competition, with this example I did I believe you will only have the competition that already exists at the time of insertion of requests.
Thank you Matheus for coming back. The value generated by the Generator does not compose the PK entirely, this ID consists of XX999999 where XXX is numeric alpha and ensures the integrity of the PK even if the Generator is restarted. The approach of the application bring the value of the increment was given because this ID is necessary after being written so that it composes the PK of the table of items.
– antonio carlos
@antoniocarlos So why don’t you check if the ID is at the allowed limit when you search for it and then restart it directly by the application? I gave an example in my reply of how to take the current value of Generator without incrementing it.
– Matheus Ribeiro
So I tried this for the application, thinking that Generator was stuck in the context of my transaction and I could manipulate this, it turns out that I did a test by putting another 5 virtual machines accessing in a prototype and what happens is that for example machine 1 makes select, returns 999 the limit for example it proceeds the change, but at this time other machines also accessed and for some they returns are 1000 , 1001, also try to process the change
– antonio carlos
Check the edition of my reply, see if it helps you with something!
– Matheus Ribeiro
Ok, I’ll test, I’ll see if this version of Dbexpress accepts the returning, thank you.
– antonio carlos