Page 1 of 1

Proposal for MSSQL issue getting identity column

Posted: 15.11.2014, 14:04
by ChrisCross
On MSSQL we can use 3 ways of getting last inserted identity in a table

1.@@IDENTITY which gets last inserted identity
2. SCOPE_IDENTITY() which gets last inserted identity in current scope
3. IDENT_CURRENT( 'table_name' ) which gets the last identity value generated for a specified table or view.

If we have a table let's say PEOPLE with IDPeople int identity(1,1) all 3 functions return the same value if we are doing a simple insert.
If we have also a trigger that logs the operations made to the PEOPLE table into a separate log table which has also an identity column then 1st function will return the id inserted in the log table and
the other 2 function will return the last IDPeople inserted in the PEOPLE table.

My proposal is to use then SCOPE_IDENTITY function instead of @@IDENTITY function for getting the wright identity in the table used.
The 3rd function is the best option but we have to get current table name in order to use it.

I replaced the @@Identity with SCOPE_IDENTITY() for example in ZDbcDbLibResultSet.pas

Code: Select all

procedure TZDBLibCachedResolver.PostUpdates(Sender: IZCachedResultSet;
  UpdateType: TZRowUpdateType; OldRowAccessor, NewRowAccessor: TZRowAccessor);
var
  Statement: IZStatement;
  ResultSet: IZResultSet;
  I: Integer;
begin
  inherited PostUpdates(Sender, UpdateType, OldRowAccessor, NewRowAccessor);

  { Defines an index of autoincrement field. }
  if FAutoColumnIndex = -1 then
    for I := FirstDbcIndex to Metadata.GetColumnCount{$IFDEF GENERIC_INDEX}-1{$ENDIF} do
      if Metadata.IsAutoIncrement(I) then
      begin
        FAutoColumnIndex := I;
        Break;
      end;

  if (UpdateType = utInserted) and (FAutoColumnIndex > InvalidDbcIndex)
    and OldRowAccessor.IsNull(FAutoColumnIndex) then
  begin
    Statement := Connection.CreateStatement;
    ResultSet := Statement.ExecuteQuery('SELECT SCOPE_IDENTITY()');
    try
      if ResultSet.Next then
        NewRowAccessor.SetLong(FAutoColumnIndex, ResultSet.GetLong(FirstDbcIndex));
    finally
      ResultSet.Close;
      Statement.Close;
    end;
  end;
end;
What is your opinion regarding this ?

Re: Proposal for MSSQL issue getting identity column

Posted: 16.11.2014, 19:03
by EgonHugeist
Hi!

I like ready patches! I did google your suggestions ... SCOPE_IDENTITY seems to be supported since SQL Server 2008.

Not a problem if you have an idea how we can determine a 2008+ Server. Any ideas?

Re: Proposal for MSSQL issue getting identity column

Posted: 16.11.2014, 23:14
by ChrisCross
Hi!
Acording to this http://technet.microsoft.com/en-us/libr ... l.80).aspx it's also suported since sql2000.

I'll try it tomorow on an instance but i'm sure of it because i made this modification some time ago and we have clients on sql2000 (hoping to upgrade soon).

Re: Proposal for MSSQL issue getting identity column

Posted: 18.11.2014, 22:18
by EgonHugeist
Geat news!

But there is still the Version check missing. Note we support MSSQL from 6.5? to 2012 and 2014(untested)? So apply this patch the way it is would lead to new bug-tickets..

Re: Proposal for MSSQL issue getting identity column

Posted: 24.11.2014, 11:51
by marcov
6.5,7 and 2000 are already out of extended support by MS it seems:

http://support2.microsoft.com/lifecycle ... &alpha=sql

For sql 2000 that date is fairly recent (2013), but the rest is *old*

Re: Proposal for MSSQL issue getting identity column

Posted: 15.01.2015, 14:21
by lrrosa
There is a global variable that returns all the information about the current version:

Code: Select all

SELECT @@VERSION
And there is a function easier to parse that returns just the version number:

Code: Select all

SELECT SERVERPROPERTY('productversion')
But I don't know if this second method is supported on SQL Server < 2000.