I have tblEmployee
that contains 3 fields:
ID
: AutoNumber
Name
: Text
Supervisor
: Number [as a lookup in tblEmployee]
I wish to append new data to this table from tblNewEmployees
that has the exact same structure as the previous table.
Can this be done if I have the ID field as an autonumber?
I have tried various queries (for example first appending only the Name field as step 1, and then trying with a second update query to get the supervisor) but all produced garbage, hence my question whether this is possible using AutoNumbers in the first place.
I suppose it can be done in your structure (adjacency list model) in an iterative way i.e. add the employee(s) at the top of the tree, query the database to get their auto-generated id(s), then add the employees in the next level down using the previously queried id(s), then repeat for each level down.
While possible, is it desirable? Presumably every employee already has a unique id e.g. payroll number, social security number, etc. If unsure, ask the payroll person.
Removing the dependency of the database in generating employee ids will probably free you from the aforementioned iterative process. It is preferable for inserts to be deterministic, predictable, scritpable as a one-off, etc.
Another thing to consider is that your may be modelling a tree structure when you may want a hierarchy. The examples Celko used to give: the army is a hierarchy because if you shoot your sergeant you still have to take orders from your captain; on the other hand, a river system is tree because if your dam one tributary then all downstream tributaries run dry.
It seems to me with your design, when a supervisor leaves (is deleted from the table) then you are left with an unsupervised employee (missing data, therefore data integrity is corrupted), whereas you'd want the next senior employee to take their place (hierarchy). An update in your structure could be a lot if work i.e. iterative again.
While the adjacency list model may be intuitive, it is not always the easiest to work with in SQL DML. Consider other models e.g. nested sets. That said, with Access, SQL DML is almost always painful because it doesn't support procedural SQL code in stored procs, triggers, etc; even a simple update can fail due to 'non-updatable query' (view) restrictions. So as usual, I must advise you to consider a more capable DBMS if at all possible.
Yes, it is possible to merge the two tables when the destination table has an AutoNumber ID. There are two possible scenarios:
Scenario 1: No overlap of ID values between the two tables
[tblEmployee]
ID Name Supervisor
-- ---------- ----------
1 Director A
2 Manager A 1
3 Worker A 2
[tblNewEmployees]
ID Name Supervisor
--- ---------- ----------
101 Director B
102 Manager B 101
103 Worker B 102
Since the Access Database Engine allows us to insert arbitrary values into an AutoNumber column, this case is trivial. Just ...
INSERT INTO tblEmployee (ID, [Name], Supervisor)
SELECT ID, [Name], Supervisor FROM tblNewEmployees
... and we're done:
[tblEmployee]
ID Name Supervisor
--- ---------- ----------
1 Director A
2 Manager A 1
3 Worker A 2
101 Director B
102 Manager B 101
103 Worker B 102
Scenario 2: Common ID values between the two tables
[tblEmployee]
ID Name Supervisor
-- ---------- ----------
1 Director A
2 Manager A 1
3 Worker A 2
[tblNewEmployees]
ID Name Supervisor
-- ---------- ----------
2 Director B
5 Manager B 2
7 Worker B 5
In this case we need to map the old ID values to the new ID values when the new rows are inserted. To do that, add a new column to [tblEmployee]
ALTER TABLE tblEmployee ADD oldID LONG
then insert the new rows, putting tblNewEmployees.ID into tblEmployee.oldID
INSERT INTO tblEmployee (oldID, [Name])
SELECT ID, [Name] FROM tblNewEmployees
giving us
[tblEmployee]
ID Name Supervisor oldID
-- ---------- ---------- -----
1 Director A
2 Manager A 1
3 Worker A 2
4 Director B 2
5 Manager B 5
6 Worker B 7
Then we can update the Supervisor column with the new ID values
UPDATE
(
tblEmployee emp
INNER JOIN
tblNewEmployees new
ON emp.oldID = new.ID
)
INNER JOIN
tblEmployee emp2
ON new.Supervisor = emp2.oldID
SET emp.Supervisor = emp2.ID
producing
[tblEmployee]
ID Name Supervisor oldID
-- ---------- ---------- -----
1 Director A
2 Manager A 1
3 Worker A 2
4 Director B 2
5 Manager B 4 5
6 Worker B 5 7
We can then drop the [oldID] column if desired.