I was browsing the code and found that sequences are not supported for MSSQL.
function MSSQL_DoGetLastAutoInc(const GeneratorName: string;Query: IDAServerDataset): variant;
begin
try
// Using Ident_Current is not fully safe
//if Trim(GeneratorName) <> '' then
// Query.SQL := 'SELECT IsNull(Ident_Current(' + QuotedStr(GeneratorName) + '), 0) as LastInc'
//else
Query.SQL := 'SELECT IsNull(@@Identity, 0) as LastInc';
Query.Open;
result := Query.Fields[0].Value;
finally
Query := nil;
end;
end;
However, checking the mechanism of PostgreSQL or Firebird, I noticed a similar mechanism is used.
function IB_GetLastAutoInc(const GeneratorName: string;Query: IDAServerDataset): Variant;
begin
try
Query.SQL:=Format('SELECT Gen_id(%s,0) FROM RDB$Database', [GeneratorName]);
Query.Open;
Result := Query.Fields[0].Value;
finally
Query:=nil;
end;
end;
Getting the value of a sequence after an insert is never correct because sequences ‘do not obey’ transactions. The value of a sequence transcends a transaction. The only correct way - in my opinion - is getting the next value before doing the actual insert. Since you’re doing 2 queries anyway, there would be no influence in performance.
Note that this is only for sequences. The current mechanism for autoinc values is correct, because the engine has a special API for it.
In addition, I changed the code in uDAADOInterfaces pending a final solution… (lines 510 up to 524)
function MSSQL_DoGetLastAutoInc(const GeneratorName: string;Query: IDAServerDataset): variant;
begin
try
if Trim(GeneratorName) <> '' then
Query.SQL := 'SELECT current_value FROM sys.sequences WHERE name = ' + QuotedStr(GeneratorName)
else
Query.SQL := 'SELECT IsNull(@@Identity, 0) as LastInc';
Query.Open;
result := Query.Fields[0].Value;
finally
Query := nil;
end;
end;
Ah yes, I believe MSSQL has built-in AutoInc field type support, so it doesn’t need a separate sequence/generator set up.
SQL Server supports sequences (since version 2012) and the AutoInc field type. When using sequences in SQL Server the MSSQL_DoGetLastAutoInc method results in a faulty value.
In my opinion bug D19276 is not fixed or am I missing something?