I'm using Access 2007. I have two tables, first one has a PK (primary key), but the second has not.
When using a query linking the two tables on the PK, I need the rows have the same sort as it is in the second table (means as records has been entered), but this doesn't happen by default, I don't know why!
Tables are just a big bucket that holds data. There is no order to them unless you supply it. Therefore, in order for the items in your query/table to appear in the order that they were entered you will have to supply something that allows Access to apply this sorting for you.
You should add an AutoNumber Primary Key to the DataSub table. This will automatically increase every time that you add new data to this table, and so you can then use this in any queries to sort by.
Regards,
Related
I need to move a table from within an ms access database to a SharePoint list. The table I need to move has had old records removed that has ID's auto increment. I need the SharePoint list to start from the same auto increment number as in the table.
I have tried using the ms access export to SharePoint list functionality but when I re-import the table back into access as a linked table to a SharePoint list the ID has started back at 1 (not 81 like in the table I uploaded to SharePoint).
I need the table to upload to the SharePoint list with the auto increment ID starting at 81 as it is in the table initially.
I understand Albert's logic, but somewhat disagree. I worked with one client that had been using an original Auto-numbered field as the Customer's ID in their access database for years, so their work orders, invoices, etc..., all have the Customer's ID there. If you use the newly-created autonumber field, then all customer id's would change to new numbers. Worse yet, if you use a 2nd, non-autonumber field as Albert recommends, then anytime you add a new customer, you would need to use a sql statement (or query) to determine the last used number from this 2nd field and increment it 1 so that it is unique. Kind of a pain.
So, the workaround is still a pain, but for a solution that does what you actually asked, you can do this. Create a new list in SharePoint with an auto-numbered field. link that list in the access database. then, look at the highest ID number (eg highest customer id) from the table with your original data... because you need to create that many rows in the SharePoint list. You can either create code to loop through creating x number of records, or if you're not comfortable with that, create an excel sheet with that many rows. then, import that excel file into the linked table. next, create a delete query which deletes all records in the linked table that doesn't have the matching ID (eg customer ID) in your access table. this leaves you with a linked list with only the IDs you are using, and it's still auto-numbering so new records are automatically assigned new numbers.
Like I said, it's a bit of a work-around. But this actually does what you are asking for, instead of being forced into a different solution.
If the column in question is a autonumber column, then during a upload or migration then those autonumbers can change. Since such numbers have NO meaning, then this should not matter. If you have several related tables then you MUST ensure that your relations are setup correctly before you move the data to sharepoint (because SharePooint will re-number these values, then the child tables and FK keys ALSO will be correctly updated). However, if you don't set the relationships, then you WILL break the related data since SharePoint does and can and will re-number the PK's used.
You are limited to ONLY using autonumber PK's if you wish to keep related tables intact. You cannot control this re-numbering, but as noted the number ONE rule in databases is that such numbers do NOT matter anyway.
If you MUST and WANT to stop the re-numbering of that column, then change the data type to a long number, and NOT autonumber type. And then of course simply add another autonumber column. So to STOP or PREVENT the numbers being changed, you have to convert the column from being autonumber to a standard long number column. (edit: you ALSO thus have to ensure that the column is NOT marked as PK).
Keep in mind that any other table as part of the related data will ALSO see those standard long number columns re-numbered and changed if that column is part of a defined relationships to some PK. So Access during a up-size WILL re-number the PK (autonumber) and will ALSO automatic for you re-number the FK columns used in child tables. If you as noted do NOT want such re-numbering to occur, then the PK and FK columns can NOT be part of a defined relationship.
So dropping the autonumber column is the only way to prevent such re-numbering. Since autonumbers don't have any real meaning, then if they are changed during a up-load, then this should not matter.
I've seen various posts here about not using lookup within a table. If you don't, how do you enforce referential integrity between a field and the allowable values from a lookup table? I can't create a relationship between the table field and the field in the lookup table because I can't create a unique (no duplicates) index on the field - the particular value needs to appear multiple times across the records in the table. But if I use the field properties to set a lookup on it and specify the field from the lookup table that it must contain, then this ensures that data can't be entered into this field that isn't in the lookup table.
Or have I got completely the wrong end of the stick here?
I recommend that you always create forms for editing records. And in those forms you can create combo boxes that perform the lookups in the correct table and field. There are options there so that you can limit the data entry to only those values which are stored in the table. This option is called Limit To List (you'll see it in the combo properties).
Another important way to enforce that data exists in your lookup table is through your Relationships.
tblProducts
ProductID (primary key)
CategoryID (foreign key)
ProductDescription
tblCategories
CategoryID (primary key)
Category
In the relationships window you would define a relationship between the two tables above on the CategoryID field. You are accomplishing several things here. It's more efficient to store only the CategoryID in your Products Table since you will be storing less data. Also, this way if you change the name on the category all records will reflect that change immediately. Every place that you display a product with its category you will need to create a combo box so that you display the Category Description as opposed to displaying the CategoryID.
As a side note, I recommend that you rarely use the Value List option as the Row Source Type in a combo. Using the Table/Query option and then creating an appropriate lookup table is a much more robust and flexible design.
So the root of this problem may lie in poor database design, some of the way this is set up is inherited from older versions. I just couldn't figure out a better way to do this.
I have four tables linked by the same field: [OBJECTID]. Each table is linked to an Access Form that controls the data. It is important that these tables be separate as the data is georeferenced and needs to be mapped separately, however they inherit several fields from one another by default.
Most of the time, the tables are in a one-to-one-to-one-to-one relationship, however occasionally, there is only data for the first table, and occasionally, there is only data for the second, third and fourth form.
Right now, the [OBJECTID] field in the first table is set to datatype autonumber, so that all subsequent linked records in the other tables can inherit that number. For the cases where the record in Tbl1 are not entered via Form1, it is easy enough to just assign a number that does not conflict with any current number, but how do I avoid assigning a number that could conflict with some future [OBJECTID] generated by the autonumber field in Tbl1?
Sorry if that is confusing! Thanks in advance for helping me think this through....
If the design is correct, there should be a relationship with referential integrity between tbl1 and table 2/3/4. Since you mention that occasionally, there is only data for the second, third and fourth form that means we have no referential integrity here :-/.
I would identify the fields that are common to all 4 tables, and create a "main" table with those, meaning that the main table MUST be filled. Then you create a 1 to 0,1 relationship to the other 4 tables, with an outer join, their PK beeing then a Long Integer.
For the source of your forms 1 to 4, use an outer join between MainTable and T1/2/3/4. The "subtables" will then inherit the PK of the main table.
Hope I am not too obscure.
I am working with a database where "almost" every table in the database has the same field and same value. For example, almost all tables have a field called GroupId and there is only one group id in the database now.
Benefits
All data is related to that field and can be identified by said field
When a new group is created data will be properly identified for the group
Disadvantages
All tables have the this field
All stored procedures need to have this field as a parameter
All queries have to filtered by this field
Is this a big deal? Is there an alternative to this approach?
Thanks
If you need to be able to identify data by more than one group in the future, having foreign keys is a good practice. However, that deosn't mean all tables need to have this field, only the ones directly related to the group. For instance a lookuptable with state values may not need it, but the customers table might. Adding it to all tables willy-nilly can lead to bad things when you try to delete a record and have to check 579 tables (only 25 of which are pertinent). All this depends greatly on what the meaning of the groups is. Most of our tables have a relationship to the client table, because they contain data related to specific clients and because we don't want various clients to have the ability to see data for other clients. Tables which do not contain that kind of data do not.
Yes most queries may need the field and many stored procs will want to have it as an input variable, but if you truly need to filter on this information, then that is as it should be.
If however there is only one group and will never be more than one group, it is a waste of time, effort and space.
So imagine you have multiple tables in your database each with it's own structure and each with a PRIMARY KEY of it's own.
Now you want to have a Favorites table so that users can add items as favorites. Since there are multiple tables the first thing that comes in mind is to create one Favorites table per table:
Say you have a table called Posts with PRIMARY KEY (post_id) and you create a Post_Favorites with PRIMARY KEY (user_id, post_id)
This would probably be the simplest solution, but could it be possible to have one Favorites table joining across multiple tables?
I've though of the following as a possible solution:
Create a new table called Master with primary key (master_id). Add triggers on all tables in your database on insert, to generate a new master_id and write it along the row in your table. Also let's consider that we also write in the Master table, where the master_id has been used (on which table)
Now you can have one Favorites table with PRIMARY KEY (user_id, master_id)
You can select the Favorites table and join with each individual table on the master_id and get the the favorites per table. But would it be possible to get all the favorites with one query (maybe not a query, but a stored procedure?)
Do you think that this is a stupid approach? Since you will perform one query per table what are you gaining by having a single table?
What are your thoughts on the matter?
One way wold be to sub-type all possible tables to a generic super-type (Entity) and than link user preferences to that super-type. For example:
I think you're on the right track, but a table-based inheritance approach would be great here:
Create a table master_ids, with just one column: an int-identity primary key field called master_id.
On your other tables, (users as an example), change the user_id column from being an int-identity primary key to being just an int primary key. Next, make user_id a foreign key to master_ids.master_id.
This largely preserves data integrity. The only place you can trip up is if you have a master_id = 1, and with a user_id = 1 and a post_id = 1. For a given master_id, you should have only one entry across all tables. In this scenario you have no way of knowing whether master_id 1 refers to the user or to the post. A way to make sure this doesn't happen is to add a second column to the master_ids table, a type_id column. Type_id 1 can refer to users, type_id 2 can refer to posts, etc.. Then you are pretty much good.
Code "gymnastics" may be a bit necessary for inserts. If you're using a good ORM, it shouldn't be a problem. If not, stored procs for inserts are the way to go. But you're having your cake and eating it too.
I'm not sure I really understand the alternative you propose.
But in general, when given the choice of 1) "more tables" or 2) "a mega-table supported by a bunch of fancy code work" ..your interests are best served by more tables without the code gymnastics.
A Red Flag was "Add triggers on all tables in your database" each trigger fire is a performance hit of it's own.
The database designers have built in all kinds of technology to optimize tables/indexes, much of it behind the scenes without you knowing it. Just sit back and enjoy the ride.
Try these for inspiration Database Answers ..no affiliation to me.
An alternative to your approach might be to have the favorites table as user_id, object_id, object_type. When inserting in the favorites table just insert the type of the favorite. However i dont see a simple query being able to work with your approach or mine. One way to go about it might be to use UNION and get one combined resultset and then identify what type of record it is based on the type. Another thing you can do is, turn the UNION query into a MySQL VIEW and simply query that VIEW.
The benefit of using a single table for favorites is a simplicity, which some might consider as against the database normalization rules. But on the upside, you dont have to create so many favorites table and you can add anything to favorites easily by just coming up with a new object_type identifier.
It sounds like you have an is-a type relationship that needs to be modeled. All of the items that can be favourited are a type of "item". It sounds like you are on the right track, but I wouldn't use triggers. What could be the right answer if I have understood correctly, is to pull all the common fields into a single table called items (master is a poor name, master of what?), this should include all the common data that would be needed when you need a users favourite items, I'd expect this to include fields like item_id (primary key), item_type and human_readable_name and maybe some metadata about when the item was created, modified etc. Each of your specific item types would have its own table containing data specific to that item type with an item_id field that has a foreign key relationship to the item table. Then you'd wrap each item type in its own insertion, update and selection SPs (i.e. InsertItemCheese, UpdateItemMonkey, SelectItemCarKeys). The favourites table would then work as you describe, but you only need to select from the item table. If your app needs the specific data for each item type, it would have to be queried for each item (caching is your friend here).
If MySQL supports SPs with multiple result sets you could write one that outputs all the items as a result set, then a result set for each item type if you need all the specific item data in one go. For most cases I would not expect you to need all the data all the time.
Keep in mind that not EVERY use of a PK column needs a constraint. For example a logging table. Even though a logging table has a copy of the PK column from the table being logged, you can't build a constraint.
What would be the worst possible case. You insert a record for Oprah's TV show into the favorites table and then next year you delete the Oprah Show from the list of TV shows but don't delete that ID from the Favorites table? Will that break anything? Probably not. When you join favorites to TV shows that record will fall out of the result set.
There are a couple of ways to share values for PK's. Oracle has the advantage of sequences. If you don't have those you can add a "Step" to your Autonumber fields. There's always a risk though.
Say you think you'll never have more than 10 tables of "things which could be favored" Then start your PK's at 0 for the first table increment by 10, 1 for the second table increment by 10, 2 for the third... and so on. That will guarantee that all the values will be unique across those 10 tables. The risk is that a future requirement will add table 11. You can always 'pad' your guestimate