I am trying to set up a database that will hold/maintain a set of user privileges. I am also using Microsoft SQL Server Management Studio.
I have made a Accounts table, with the PK= UserId.
I have made a Profiles table with the PK=ProfileId
I Have made a UserPrivileges table using the following SQL statement
CREATE TABLE UserPermissions
(
UserId int REFERENCES Accounts (UserId),
ProfileId int REFERENCES Profiles (ProfileId),
PRIMARY KEY (UserId, ProfileId)
)
But when I execute a Select query from the UserPrivileges table, nothing is returned even though I do have a few entries in the 2 previous tables.
From my understanding of foreign keys, their values are taken from the referenced table. And since the referenced tables do have entries, why are none being entered into the UserPrivileges table?
A foreign key is just a reference. If doesn't mean that you don't need entries in your table. You need them! But these entries has also to exist in the related table. Here is a very good explanation: http://www.w3schools.com/sql/sql_foreignkey.asp
First, you didn't create a UserPrivileges table. You created a UserPermissions table. (If we're to believe your code.)
Second, no rows are being entered in UserPermissions because you didn't insert any rows into UserPermissions. Foreign keys don't make rows appear as if by magic. You decide which rows belong in UserPermissions, and you insert them.
Related
Have a table sample_tag which already exists with 1000's of entries.
It consists of two foreign keys, sample_id and tag_id.
However, the database is allowing duplicate sample_id/tag_id records to be created.
Without creating a new table, is there a SQL statement to update the sample_tag table such that the two foreign keys, together, function as its primary key?
Database is MySQL using phpMyAdmin
The main challenge is how you resolve the duplicates. If there are already duplicate keys, then you'll need to address these as a separate step (either deleting the duplicate, or merging any other columns as you see fit).
To check for duplicates, try:
SELECT sample_id, tag_id, COUNT( * )
FROM sample_tag
GROUP BY sample_id, tag_id;
If there are none, then you can go ahead and delete any existing primary key, and create a new one.
I am currently writing a application in C# that uses a SQLite database to store information the user will input. The application is basically a Management system for users who are called "Students" in the application. This is the most important table in my database and every other table is linked off this table. What I want to do is when a student is removed - they leave the institute/get kicked out etc. - is to remove their data from all the other tables so that data is no longer there as it isn't needed. An example of some of the Create table statements I have written is:
CREATE TABLE student(studentID int(5) PRIMARY KEY NOT NULL, name string(16),...,DOB string(8) );
CREATE TABLE emergencyContact(emergencyID int(5) PRIMARY KEY NOT NULL, name string(16),..., contactNumber int(16));
CREATE TABLE emergencyContactOf(studentID int(5) FOREIGN KEY REFERENCES student('studentID'), emergencyID int(5) FOREIGN KEY REFERENCES emergencyContact('emergencyID');
I have read up on this and my understanding is the data will be deleted in the EmergencyContactOf table if I include a 'ON DELETE CASCADE' statement as the StudentID key will no longer be present in the Parent table.
However, my understanding is the data in the EmergencyContact table that is for that specific student will not be deleted as there is no reference to the StudentID.
My question is, is there a way to remove the data from this table also that is relevant to that Student? For example, if I was to include a column in the EmergencyContact table which would reference the StudentID as a Foreign Key and then remove that row if the StudentID is ever deleted from the parent table? Is this a good solution to this particular problem?
All other tables I have are also designed in this way, where the data is in different tables and then linked back to the Student table with relationship tables so this will also apply to all the other tables I have.
Thanks.
My question is, is there a way to remove the data from this table also that is relevant to that Student? For example, if I was to include a column in the EmergencyContact table which would reference the StudentID as a Foreign Key and then remove that row if the StudentID is ever deleted from the parent table? Is this a good solution to this particular problem?
What happens if multiple students have the same emergency contact? You don't want to duplicate data if you don't have to - that's the whole point of the emergencyContactOf table, to efficiently set up a many to many relation between students and emergency contacts. So you don't want to do something like you describe.
You could periodically (Monthly, yearly, after purging student rosters, whatever) run a delete that removes rows from emergencyContact if they don't appear in emergencyContactOf:
DELETE FROM emergencyContact
WHERE emergencyID NOT IN (SELECT emergencyID FROM emergencyContactOf)
or the like.
Hmm, I see two scenarios here. What if two students have the same emergency contact, say two bothers having their father as emergency contact?
If in such a case you store only one record (the father) in the emergency contact table, you don't want to delete the emergency contact if only one of them leaves. You'd delete the emergency contact for the other one. So you'd need additional logic, when to delete an emergency contact. You could put that in a trigger.
You use a less sophisticated approach and multiple rows from the emergency contact table can map to one person in real life. In that case you can pull the reference to the student directly into the emergency contact table and use ON DELETE CASCADE there.
CREATE TABLE student
(studentid int(5),
name string(16),
...
PRIMARY KEY (studentid),
...);
...
CREATE TABLE emergencycontact
(emergencycontactid int(5),
studentid int(5),
name string(16),
...
PRIMARY KEY (emergencycontactid),
FOREIGN KEY (studentid)
REFERENCES student
(studentid),
...);
The second might be tempting but the "clean way" is the first one, as the second allows contradicting data. From what you posted you're already on the "clean way". But a mentioned that required triggers.
Very new to SQL and have spent a day on this already.
Here are my two tables:
Centre(cid, name, location, nurse_supervisor)
Nurse(nid, name, centre_id, certificate)
I have a big problem. The (nurse_supervisor) in Centre is a foreign key to Nurse (nid).
The (centre_id) in Nurse is a foreign key to (Centre cid).
I can't figure out how to populate these tables. I have tried:
INSERT ALL, which produces "A foreign key value has no matching primary key value"
I have tried removing the foreign key constraints and adding them after populating the tables but when I do that it says I can't add a constraint to tables with preexisting data.
I tried removing NOT NULL - but realized that was silly as the constraints will be enforced anyways.
Everything I look through says populate the parent table first and then the child, but these tables are linked to each other.
I am using SQL developer.
This is a poor schema design, but one way to get around it would be to:
Make both centre_id and nurse_supervisor columns NULL in the two table definitions
Insert all rows into both tables, but with NULL for those two columns
Update centre_id to the correct value for each row in the Nurse table
Update nurse_supervisor to the correct value for each row in the Centre table
I have a database table called Lesson:
columns: [LessonID, LessonNumber, Description] ...plus some other columns
I have another table called Lesson_ScoreBasedSelection:
columns: [LessonID,NextLessonID_1,NextLessonID_2,NextLessonID_3]
When a lesson is completed, its LessonID is looked up in the Lesson_ScoreBasedSelection table to get the three possible next lessons, each of which are associated with a particular range of scores. If the score was 0-33, the LessonID stored in NextLessonID_1 would be used. If the score was 34-66, the LessonID stored in NextLessonID_2 would be used, and so on.
I want to constrain all the columns in the Lesson_ScoreBasedSelection table with foreign keys referencing the LessonID column in the lesson table, since every value in the Lesson_ScoreBasedSelection table must have an entry in the LessonID column of the Lesson table. I also want cascade updates turned on, so that if a LessonID changes in the Lesson table, all references to it in the Lesson_ScoreBasedSelection table get updated.
This particular cascade update seems like a very straightforward, one-way update, but when I try to apply a foreign key constraint to each field in the Lesson_ScoreBasedSelection table referencing the LessonID field in the Lesson table, I get the error:
Introducing FOREIGN KEY constraint 'c_name' on table 'Lesson_ScoreBasedSelection' may cause cycles or multiple cascade paths.
Can anyone explain why I'm getting this error or how I can achieve the constraints and cascading updating I described?
You can't have more than one cascading RI link to a single table in any given linked table. Microsoft explains this:
You receive this error message because
in SQL Server, a table cannot appear
more than one time in a list of all
the cascading referential actions that
are started by either a DELETE or an
UPDATE statement. For example, the
tree of cascading referential actions
must only have one path to a
particular table on the cascading
referential actions tree.
Given the SQL Server constraint on this, why don't you solve this problem by creating a table with SelectionID (PK), LessonID, Next_LessonID, QualifyingScore as the columns. Use a constraint to ensure LessonID and QualifyingScore are unique.
In the QualifyingScore column, I'd use a tinyint, and make it 0, 1, or 2. That, or you could do a QualifyingMinScore and QualifyingMaxScore column so you could say,
SELECT * FROM NextLesson
WHERE LessonID = #MyLesson
AND QualifyingMinScore <= #MyScore
AND #MyScore <= QualifyingMaxScore
Cheers,
Eric
How do you create a one to many relationship using SQL Server?
Define two tables (example A and B), with their own primary key
Define a column in Table A as having a Foreign key relationship based on the primary key of Table B
This means that Table A can have one or more records relating to a single record in Table B.
If you already have the tables in place, use the ALTER TABLE statement to create the foreign key constraint:
ALTER TABLE A ADD CONSTRAINT fk_b FOREIGN KEY (b_id) references b(id)
fk_b: Name of the foreign key constraint, must be unique to the database
b_id: Name of column in Table A you are creating the foreign key relationship on
b: Name of table, in this case b
id: Name of column in Table B
This is a simple example of a classic Order example. Each Customer can have multiple Orders, and each Order can consist of multiple OrderLines.
You create a relation by adding a foreign key column. Each Order record has a CustomerID in it, that points to the ID of the Customer. Similarly, each OrderLine has an OrderID value. This is how the database diagram looks:
In this diagram, there are actual foreign key constraints. They are optional, but they ensure integrity of your data. Also, they make the structure of your database clearer to anyone using it.
I assume you know how to create the tables themselves. Then you just need to define the relationships between them. You can of course define constraints in T-SQL (as posted by several people), but they're also easily added using the designer. Using SQL Management Studio, you can right-click the Order table, click Design (I think it may be called Edit under 2005). Then anywhere in the window that opens right-click and select Relationships.
You will get another dialog, on the right there should be a grid view. One of the first lines reads "Tables and Columns Specification". Click that line, then click again on the little [...] button that appears on the right. You will get this dialog:
The Order table should already be selected on the right. Select the Customer table on the left dropdown. Then in the left grid, select the ID column. In the right grid, select the CustomerID column. Close the dialog, and the next. Press Ctrl+S to save.
Having this constraint will ensure that no Order records can exist without an accompanying Customer record.
To effectively query a database like this, you might want to read up on JOINs.
This is how I usually do it (sql server).
Create Table Master (
MasterID int identity(1,1) primary key,
Stuff varchar(10)
)
GO
Create Table Detail (
DetailID int identity(1,1) primary key,
MasterID int references Master, --use 'references'
Stuff varchar(10))
GO
Insert into Master values('value')
--(1 row(s) affected)
GO
Insert into Detail values (1, 'Value1') -- Works
--(1 row(s) affected)
insert into Detail values (2, 'Value2') -- Fails
--Msg 547, Level 16, State 0, Line 2
--The INSERT statement conflicted with the FOREIGN KEY constraint "FK__Detail__MasterID__0C70CFB4".
--The conflict occurred in database "Play", table "dbo.Master", column 'MasterID'.
--The statement has been terminated.
As you can see the second insert into the detail fails because of the foreign key.
Here's a good weblink that shows various syntax for defining FK during table creation or after.
http://www.1keydata.com/sql/sql-foreign-key.html
If you are not using SSMS then here is the syntax:
ALTER TABLE <table_name>
ADD <constraint_name> FOREIGN KEY
(<column_name1> ,
<column_name2> )
REFERENCES <table_name>
(<column_name1> ,
<column_name2>)
http://infogoal.com/sql/sql-add-foreignkey.htm
If you are talking about two kinds of enitities, say teachers and students, you would create two tables for each and a third one to store the relationship. This third table can have two columns, say teacherID and StudentId.
If this is not what you are looking for, please elaborate your question.