tags:

views:

163

answers:

4

I have an access table with an automatic primary key, a date, and other data. The first record starts at 36, due to deleted records. I want to change all the primary keys so they begin at 1 and increment, ordered by the date. Whats the best way to do this?

I want to change the table from this:

| TestID | Date     | Data |
|  36    | 12/02/09 | .54  |
|  37    | 12/04/09 | .52  |

To this:

| TestID | Date     | Data |
|  1     | 12/02/09 | .54  |
|  2     | 12/04/09 | .52  |

EDIT: Thanks for the input and those who answered. I think some were reading a little too much into my question, which is okay because it still adds to my learning and thinking process. The purpose of my question was two fold: 1) It would simply be nicer for me to have the PK match with the order of my data's dates and 2) to learn if something like this was possible for later use. Such as, if I want to add a new column to the table which numbers the tests, labels the type of test, etc. I am trying to learn a lot at once right now so I get a little confused where to start sometimes. I am building .NET apps and trying to learn SQL and database management and it is sometimes confusing finding the right info with the different RDMS's and ways to interact with them.

+3  A: 

I would create a new table, with autoincrement.

Then select all the existing data into it, ordering by date. That will result in the IDs being recreated from "1".

Then you could drop the original table, and rename the new one.

Assuming no foreign keys - if so you'd have to drop and recreate those too.

MikeW
That seems to be the easiest way. But for educational purposes, how would I loop through the table to change each one, using a counter?
ScottK
See above. -------
martinr
The best way (original question asked) is not to, but if you have to, MikeW is the next best way. Please update your question if you want the best way to do it with a loop. Smells like a homework question.
Michael Wheeler
@Michael Wheeler: Its not a homework question, its a table I created at work. I am refreshing my SQL so this is all for my own educational purposes. I have been working with .net languages so my first instinct is to loop through the records to change them.
ScottK
@Scott: Loops and SQL repel each other. Check my answer for the SQL-way to copy the data from the old table to the new one.
Daniel Vassallo
@Daniel: What is the question number you are referring to?
ScottK
@Scott: This question :)
Daniel Vassallo
Jet/ACE Autonumber fields are not updatable, so the answer to "how would I loop through the table to change each one, using a counter?" is YOU CAN'T.
David-W-Fenton
+3  A: 

Following from MikeW, you can use the following SQL command to copy the data from the old to the new table:

INSERT 
    TestID, Date, Data
INTO
    NewTable
SELECT
    TestID, Date, Data
FROM
    OldTable;

The new TestID will start from 1 if you use an AutoIncrement field.

Daniel Vassallo
+2  A: 

An Autonumber used as a surrogate primary keys is not data, but metadata used to do nothing but connect records in related tables. If you need to control the values in that field, then it's data, and you can't use an Autonumber, but have to roll your own autoincrement routine. You might want to look at this thread for a starting point, but code for this for use in Access is available everywhere Access programmers congregate on the Net.

David-W-Fenton
A: 

I agree that the value of the auto-generated IDENTITY values should have no meaning, even for the coder, but for education purposes, here's how to reseed the IDENTITY using ADO:

ACC2000: Cannot Change Default Seed and Increment Value in UI

Note the article as out of date because it says, "there are no options available in the user interface (UI) for you to make this change." In later version the Access, the SQL DLL could be executed when in ANSI-92 Query Mode e.g. something like this:

ALTER TABLE MyTable ALTER TestID INTEGER IDENTITY (1, 1) NOT NULL;

onedaywhen
I'm surprised you're not recommending ADO for this, as it executes in "SQL 92" mode, and is available in all the Jet 4 versions of Access. You know I'm no friend of ADO, but this is one place where I actually use it (I wrote code to do this just last week because I was appending some old data from an archive that had Autonumber values lower than the current Max() and needed to reset it after the append).
David-W-Fenton
"I'm surprised you're not recommending ADO for this" -- the OP seems to be using .NET so I would not recommend ADO classic. They'll probably be using OLE DB, which is ANSI-92 Query Mode. Note (again!) that it is ANSI-92 Query Mode and not "SQL 92".
onedaywhen
Noted about "ANSI-92", but is it not the case that you'd have to pass the Jet OLE-DB provider SQL that is compatible with what is called in the Access UI "SQL 92" mode, rather than strict ANSI-92 SQL?
David-W-Fenton
Ah, the Access UI calls it "SQL 92" modem eh? Sorry, I didn't realize. Yes, it's a misnomer anyhow.
onedaywhen
It may be a misnomer, but you didn't answer the question -- don't you have to write your SQL using the SQL compatible with Jet/ACE, rather than writing it against the ANSI-92 standard?
David-W-Fenton