I'm pretty new to MS Access 2007, and I wanted to ask about something, that I couldn't find.
Is it possible that in a specific column, say for example: type, to make the only possible values "typea", "typeb"?
Just like the yes/no available option, just that it will contain my own specific values.
Yes you can create a lookup table with the id and description (typea/typeb) values in and then reference this table. You can add a check constraint on the column to ensure the type entered matches the constraint specified. (typea or typeb).
There is a way that involves only the basics. Create a reference table for the valid values of Type. It might have two columns, Id and Description. The primary key is Id.
Put two rows in with Id values of "typea" and "typeb". Put whatever you want for the description. You might use this later.
Use the relationship tool to make the column in your existing table reference the Id column in the types table. This will create a references constraint in the database.
Another response suggested adding a check constraint. That will probably run faster, but may involve more learning on your part.
And, if you ever add a third and fourth type, having a table like the one I've given will make it super easy to modify.
Related
I'm not sure the proper terminology for this type of relationship or even if it's good or bad. Hopefully I can clear up the lousy title.
I have a table that has the following fields:
id(pk), type, data(fk)
I want to be able to change the table that data points to depending on what "type" is. Depending on the type, there might be different types of data I need to pull. I'm basically trying to create a variable relationship.
You cannot do this in MySQL. You want conditional relationships.
You have basically three choices.
You can ignore putting these relationships in the database.
You can use before insert and before update triggers to enforce the constraints.
You can add a separate column for each type of id and add the constraints to those columns.
I am new in microsoft access. I was just wondering on how can I use create a custom primary key? for example abc-123 format?
It depends on how you want the abc-123 values to be created.
If you want to create them by yourself in your code, just create a Text column and use that as your primary key.
If you want Access to create these values...that's not really possible. The only thing that Access is able to auto-generate are increasing numerical values (data type AutoNumber).
So the best thing you can do is to use an AutoNumber internally as the actual primary key, and create the abc-123 value out of that, just for displaying.
Here are some examples how to do this, from previous similar questions that I answered in the past:
access 2003 text display leading zero
Automatically generate numbers
Disclaimer: I don't know if a similar approach would work in your case.
If not, you need to give more information how exactly you want your numbers to be created:
do you want the number to increase?
do you want the letters to change/"increase"/always stay the same?
Actually, you could create a table trigger if using 2010 or later. The table trigger could take some field (where you get the abc from) and then some other field (seq num) and then add + 1 to the value.
The "air" code would look like this:
The beauty of the table trigger is it runs at table (data engine) level, and thus if you open the database with ODBC, VB.net, FoxPro, Access etc. then the PK key will always auto generate for you.
I would like to restrict a column value in a SQL table. For example, the column values can only be "car" or "bike" or "van". My question is how do you achieve this in SQL, and is it a good idea to do this on the DB side or should I let the application restrict the input.
I also have the intention to add or remove more values in the future, for example, "truck".
The type of Databases I am using are SQLite and MySQL.
Add a new table containing these means of transport, and make your column a foreign key to that table. New means of transport can be added to the table in future, and your column definition remains the same.
With this construction, I would definitively choose to regulate this at the DB level, rather than that of the application.
For MySQL, you can use the ENUM data type.
column_name ENUM('small', 'medium', 'large')
See MySQL Reference: The ENUM Type
To add to this, I find it's always better to restrict on the DB side AND on the app side. An Enum plus a Select box and you're covered.
Yes, it is recommended to add check constraints. Check constraints are used to ensure the validity of data in a database and to provide data integrity. If they are used at the database level, applications that use the database will not be able to add invalid data or modify valid data so the data becomes invalid, even if the application itself accepts invalid data.
In SQLite:
create table MyTable
(
name string check(name = "car" or name = "bike" or name = "van")
);
In MySQL:
create table MyTable
(
name ENUM('car', 'bike', 'van')
);
You would use a check constraint. In SQL Server it works like this
ALTER TABLE Vehicles
ADD CONSTRAINT chkVehicleType CHECK (VehicleType in ('car','bike','van'));
I'm not sure if this is ANSI standard but I'm certain that MySQL has a similar construct.
If you want to go with DB-side validation, you can use triggers. See this for SQLite, and this detailed how-to for MySQL.
So the question is really whether you should use Database validation or not. If you have multiple clients -- whether they are different programs, or multiple users (with possibly different versions of the program) -- then going the database route is definitely best. The database is (hopefully) centralized, so you can decouple some of the details of validation. In your particular case, you can verify that the value being inserted into the column is contained in a separate table that simply lists valid values.
On the other hand, if you have little experience with databases, plan to target several different databases, and don't have the time to develop expertise, perhaps simple application level validation is the most expedient choice.
To add some beginner level context to the excellent answer of #NGLN above.
First, one needs to check the foreign key constraint is active, otherwise sqlite won't limit to the input to the column to the reference table:
PRAGMA foreign_key;
...which gives a response of 0 or 1, indicating on or off.
To set the foreign key constraint:
PRAGMA foreign_keys = ON;
This needs to be set to ensure that sqlite3 enforces the constraint.
I found it simplest to just set the primary key of the reference table to be the type. In the OP's example:
CREATE TABLE IF NOT EXISTS vehicle_types(
vehicle_type text PRIMARY KEY);
Then, one can insert 'car', 'bike' etc into the vehicle_types table (and more in the future) and reference that table in the foreign key constraint in the child table (the table in which the OP wished to reference the type of vehicle):
CREATE TABLE IF NOT EXISTS ops_original_table(
col_id integer PRIMARY KEY,
...many other columns...
vehicle_type text NOT NULL,
FOREIGN KEY (vehicle_type) REFERENCES vehicle_types(vehicle_type);
Outwith the scope of the OP's question but also take note that when setting up a foreign key constraint thought should be given to what happens to the column in child table (ops_original_table) if a parent table value (vehicle_types) is deleted or updated. See this page for info
I was wondering if there is a way to create a foreign key for a list of integers that responds on single integer elements of the list.
For example, I have an "exercises" table. On that table, I would like to maintain two related columns:
"exercisesID"
"relatedExerciseIDs"
However, "relatedExerciseIDs" is a VARCHAR containing comma-delimited "exerciseID"s. On a deletion of an exercise from the table, any exercises with the deleted "exerciseID" in their "relatedExerciseIDs" list should remove it.
Is this possible? How can I do this?
Thanks for your opinions! I would also be interested in using a column type other than a VARCHAR if shown possible =)
All column values should be atomic.
You should not have a list of anything you want to query inside a single value.
The way to relate exercises to other exercises is with a second table. It will have two columns, each holding an exercise ID, where both columns are a foreign reference the exercises table.
The only way to do that is either via a stored procedure or in your language of choice. When you delete the record, you would then have to do a LIKE query to find any record with the value in your delimited field. It's really not the best way to do things, and would be slow as hell since you can't index that field the way you need to.
Your absolute best bet would be to create another table to define the relationships between exercises, using just two exercise id fields (exercise_id, related_exercise_id).
You should read up on Database Normalization.
I'm sure this is either totally impossible or really easy:
If I'm creating a table and I want one of the columns to have limited options, it seems that I use either the ENUM or SET value type. But I have to define the possible values at that moment. What if I have another table which has two columns, a primary key column and a data column, and I want the ENUM for my new table to be set to the primary key of the already existing column?
I'm sure I can just write in the values long-hand, but ideally what I need is for new values to be entered into the list table and for the table with the enum column to just accept that the value choices will include anything new added to that list table.
Is this possible without needing to manipulate the structure of the new table each time something is added to the list?
i think this link help :
http://dev.mysql.com/doc/refman/5.0/en/enum.html
have a discussion of it
in the user comments
start :
"In MySQL 5.0, you can convert an enum's values into a dynamically-defined table of values, which then provides effectively a language-neutral method to handle this kind of conversion (rather than relying on PHP, Tcl, C, C++, Java, etc. specific code).
"
he do it with stored PROCEDURE
The easiest way is to use a regular column without contraints. If you're interested in all the current values, use DISTINCT to query them:
select distinct YourColumn from YourTable
That way, you don't have any maintenance and can store whatever you like in the table.
The foreign key table you mention is also a good option. The foreign key will limit the original column. Before you do the actual insert, you run a query to expand the "enum" table:
insert into EnumTable (name)
select 'NewEnumValue'
where not exists (select * from EnumTable where name = 'NewEnumValue')
Not sure what exactly you're trying to achieve btw; limit the column, but automatically expand the choices when someone breaks the limit?