Link to home
Start Free TrialLog in
Avatar of Stef Merlijn
Stef MerlijnFlag for Netherlands

asked on

SQL Server: Change Integer to AutoInc from within Delphi

Hi,

How can I change a field of type Integer into field of type AutoInc in SQL Server from within Delphi?
The data in the field is unique.

Thanks, Stef
Avatar of Daniel Wilson
Daniel Wilson
Flag of United States of America image

From Delphi (or anywhere else you can execute SQL), execute the following SQL.

This assumes that the actual values in the ID column are not important.  If they are ... not sure ...

Also, execute each statement separately.


Alter Table EEQ Add ID2 int not null identity(1,1);
Alter Table EEQ Drop Column ID;
exec sp_rename 'EEQ.ID2', 'ID', 'Column';

Open in new window

Avatar of Stef Merlijn

ASKER

The actual values in the current Integer-field are important to be kept in the AutoInc-field.
So your approach probably want work for that.
OK, you're going to need to:
  • Create a new table that uses IDENTITY in the appropriate field
  • turn Identity_Insert on for that table
  • Select into that table from your live one
  • drop your live table
  • Rename the new table to the live name
Need code for that?
Yes I would like to have some code for that.
Bye the way, I have to migrate my MS Access database to SQL Server. Maybe this can be done at the same time?
You might do that migration now ...

To create the table, use SSMS to script the existing table, but tweak that column's script to say INT NOT NULL IDENTITY (1,1) instead of just INT.  Also come up w/ a new name for the CREATE TABLE statement.

Set Identity_Insert NewTableName ON
Insert Into NewTableName (field1, field2, etc.) (Select Field1, field2, etc.) from OriginalTable
Drop Table OriginalTable
sp_rename 'NetTableName', 'OriginalTable', 'TABLE'
Here is the situation:
I upsized the MS Access table to SQL Server.
All AutoInc fields are currently changed to Integer fields in SQL Server.

I will distribute an empty database (no records) to existing customers. The whole data conversion will be done from within my Delphi application. The customer should just be able to run the exe and all is done automatically.
My idea was to insert the AutoInc-value from MS Access database into an Integer-field in SQL server and then change the fieldtype in SQL Server.

Can you supply me with some details on how to proceed next?
Can I somehow set Indentity on an existing Integer-field?

Like:
ALTER Table EEQ ALTER ID2 int not null identity(1,1);

And how can I do that from within Delphi?
ASKER CERTIFIED SOLUTION
Avatar of Daniel Wilson
Daniel Wilson
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Could you give me an example on how to convert an MS Access database to SQL Server?
The code below is the one I currently use, but this will not work when with AutoInc fields and the values from MS Access will be re-numbered during conversion in MS SQL Server.
procedure TDM.ConverteerDB;
var
  sl: TStringlist;
  i, j: Integer;
  veld: TField;
  veldnaam: String;
begin
  sl := TStringlist.Create;
  ADOConnectionAccess.GetTableNames(sl, False);
  for i := 0 to Pred(sl.Count) do
  begin
    ADOTableAccessConversie.TableName := sl[i];
    ADOTableAccessConversie.Open;
    ADOTableAccessConversie.First;
    ADOTableSQLConversie.TableName := sl[i];
    ADOTableSQLConversie.Open;
    while (not ADOTableAccessConversie.Eof) do
    begin
      ADOTableSQLConversie.Insert;
      for j := 0 to Pred(ADOTableAccessConversie.FieldCount) do
      begin
        Veld := ADOTableAccessConversie.FieldList.Fields[j];
        Veldnaam := veld.FieldName;
        try
          if ((Veld.DataType = ftWideString) OR (Veld.DataType = ftMemo) OR (Veld.DataType = ftWideMemo)) then
            ADOTableSQLConversie.FieldByName(Veldnaam).AsString := ADOTableAccessConversie.FieldByName(veldnaam).AsString
          else if ((Veld.DataType = ftInteger) OR (Veld.DataType = ftAutoinc)) then
            ADOTableSQLConversie.FieldByName(veldnaam).AsInteger := ADOTableAccessConversie.FieldByName(veldnaam).AsInteger
          else if (Veld.DataType = ftBoolean) then
            ADOTableSQLConversie.FieldByName(veldnaam).AsBoolean := ADOTableAccessConversie.FieldByName(veldnaam).AsBoolean
          else if (Veld.DataType = ftDateTime) then
            ADOTableSQLConversie.FieldByName(veldnaam).AsDateTime := ADOTableAccessConversie.FieldByName(veldnaam).AsDateTime
          else if (Veld.DataType = ftFloat) then
            ADOTableSQLConversie.FieldByName(veldnaam).AsFloat := ADOTableAccessConversie.FieldByName(veldnaam).AsFloat
          else if (Veld.DataType = ftBlob) then
            ADOTableSQLConversie.FieldByName(veldnaam).asVariant := ADOTableAccessConversie.FieldByName(veldnaam).AsVariant;
        except
          ShowMessage('Erro with field: ' + veldnaam + ' in tabel: ' + sl[i]);
        end;
      end;
      ADOTableSQLConversie.Post;
      ADOTableAccessConversie.Next;
    end;
    ADOTableSQLConversie.Close;
    ADOTableAccessConversie.Close;
  end;
end;

Open in new window

The usually-recommended method is to use MS' Access Upsize Wizard.

Not sure how to do it in code ...
Does anybody have an solution for this?

Woulld something like this be allowed? Works with MS Access on a integer field.
ALTER Tabel MyTable ALTER Column ID Counter
like
ALTER Tabel MyTable ALTER Column ID int not null identity(1,1);
Maybe the starting ID must be set to the MAX(ID) + 1