473,408 Members | 2,052 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,408 software developers and data experts.

Referential Integrity problem

I'm using Microsoft SQL Server Management Studio Express 9.00.2047.00
and expriencing problems with setting referential integrity on a link
table. The tables' schema is as follows:
-------------------------------------------------------------------
CREATE TABLE competencies (
CID bigint identity(1,1) CONSTRAINT pk_CID PRIMARY KEY,
LockedBy bigint DEFAULT 0 NOT NULL
CONSTRAINT fk_UserID
REFERENCES usr_info(userID)
ON DELETE SET DEFAULT
ON UPDATE CASCADE
)
---------------------------------------------------------
CREATE TABLE usr_info (
userID bigint IDENTITY(0,1) CONSTRAINT pk_UID PRIMARY KEY,
ActiveFlag bit default 0 NOT NULL, --(1='Yes', 0='No')
FirstName varchar(100) default '' NOT NULL,
LastName varchar(100) default '' NOT NULL
)
-------------------------------------------------------
CREATE TABLE competency_hdr (
fkCID bigint default 0 NOT NULL
CONSTRAINT fkCID_ch
REFERENCES competencies(CID)
ON DELETE CASCADE
ON UPDATE CASCADE,
ApprovedBy bigint default 0 NOT NULL
CONSTRAINT fkUserID_ch
REFERENCES usr_info(userID)
ON DELETE SET DEFAULT -- NO delete if user is deleted
ON UPDATE CASCADE
)
--------------------------------------------------------
When I execute the above I get the following error message.

Msg 1785, Level 16, State 0, Line 1
Introducing FOREIGN KEY constraint 'fkUserID_ch' on table
'competency_hdr' may cause cycles or multiple cascade paths. Specify
ON DELETE NO ACTION or ON UPDATE NO ACTION, or modify other FOREIGN
KEY constraints.
Msg 1750, Level 16, State 0, Line 1
Could not create constraint. See previous errors.

Now, if i swap the fields around then the error message changes to
that of the fkCID field.

Basically what I want is:
when I delete a competency record I need all references to this record
to be deleted.
when I delete a user I want to set the foreign key to zero (the record
must remain on the database).

Obviously there is something I'm missing here. Any advice, anyone?
---------------------------------------------------------------
jn******@yourpantsyahoo.com.au : Remove your pants to reply
---------------------------------------------------------------
Jun 3 '06 #1
6 4931
Jeff North (jn******@yahoo.com.au) writes:
When I execute the above I get the following error message.

Msg 1785, Level 16, State 0, Line 1
Introducing FOREIGN KEY constraint 'fkUserID_ch' on table
'competency_hdr' may cause cycles or multiple cascade paths. Specify
ON DELETE NO ACTION or ON UPDATE NO ACTION, or modify other FOREIGN
KEY constraints.
Msg 1750, Level 16, State 0, Line 1
Could not create constraint. See previous errors.

Now, if i swap the fields around then the error message changes to
that of the fkCID field.

Basically what I want is:
when I delete a competency record I need all references to this record
to be deleted.
when I delete a user I want to set the foreign key to zero (the record
must remain on the database).

Obviously there is something I'm missing here. Any advice, anyone?


SQL Server is extremly conservative with cascading foreign keys. If there
is the slightest suspecion there could be trouble, it won't permit you
define the cascade path. I can't really say what might be the problem
in this case, but I guess that if you add triggers into the mix, there
can be intersting results.

One way to handle cascading updates and deletes is to use triggers. The
drawback with this is that you cannot have any declarative referential
integrity at all, as constraints are checked before triggers fire.

A better approach is probably to use a stored procedure that performs
the cascade from bottom up. That is, it first deletes the children and
then the children.

By the way, having 0 as a dummy user for "no one at all", is probably
not the best design. I would rather use NULL for this.
--
Erland Sommarskog, SQL Server MVP, es****@sommarskog.se

Books Online for SQL Server 2005 at
http://www.microsoft.com/technet/pro...ads/books.mspx
Books Online for SQL Server 2000 at
http://www.microsoft.com/sql/prodinf...ons/books.mspx
Jun 3 '06 #2
On Sat, 3 Jun 2006 17:34:14 +0000 (UTC), in
comp.databases.ms-sqlserver Erland Sommarskog <es****@sommarskog.se>
<Xn**********************@127.0.0.1> wrote:
| Jeff North (jn******@yahoo.com.au) writes:
| > When I execute the above I get the following error message.
| >
| > Msg 1785, Level 16, State 0, Line 1
| > Introducing FOREIGN KEY constraint 'fkUserID_ch' on table
| > 'competency_hdr' may cause cycles or multiple cascade paths. Specify
| > ON DELETE NO ACTION or ON UPDATE NO ACTION, or modify other FOREIGN
| > KEY constraints.
| > Msg 1750, Level 16, State 0, Line 1
| > Could not create constraint. See previous errors.
| >
| > Now, if i swap the fields around then the error message changes to
| > that of the fkCID field.
| >
| > Basically what I want is:
| > when I delete a competency record I need all references to this record
| > to be deleted.
| > when I delete a user I want to set the foreign key to zero (the record
| > must remain on the database).
| >
| > Obviously there is something I'm missing here. Any advice, anyone?
Thanks for your response, much appreciated.
| SQL Server is extremly conservative with cascading foreign keys. If there
| is the slightest suspecion there could be trouble, it won't permit you
| define the cascade path.
Thank goodness it's the app. I thought I was misunderstanding
something.
| I can't really say what might be the problem
| in this case, but I guess that if you add triggers into the mix, there
| can be intersting results.
No triggers at present but it looks as though triggers might be the
only option.
| One way to handle cascading updates and deletes is to use triggers. The
| drawback with this is that you cannot have any declarative referential
| integrity at all, as constraints are checked before triggers fire.
|
| A better approach is probably to use a stored procedure that performs
| the cascade from bottom up. That is, it first deletes the children and
| then the children.
More maintenance woes :-(
| By the way, having 0 as a dummy user for "no one at all", is probably
| not the best design. I would rather use NULL for this.


Agreed but there are always exceptions to the rule :-)
---------------------------------------------------------------
jn******@yourpantsyahoo.com.au : Remove your pants to reply
---------------------------------------------------------------
Jun 3 '06 #3
Jeff North (jn******@yahoo.com.au) writes:
On Sat, 3 Jun 2006 17:34:14 +0000 (UTC), in
comp.databases.ms-sqlserver Erland Sommarskog <es****@sommarskog.se>
<Xn**********************@127.0.0.1> wrote:
| I can't really say what might be the problem
| in this case, but I guess that if you add triggers into the mix, there
| can be intersting results.


No triggers at present but it looks as though triggers might be the
only option.


What I wanted to say that combination of cascading DRI (had it been
permitted) and triggers in this case could have lead to interesting
results. And since a trigger could be added later, my suspicion that the
mere possibility is enough to disallow the multiple cascade path.
--
Erland Sommarskog, SQL Server MVP, es****@sommarskog.se

Books Online for SQL Server 2005 at
http://www.microsoft.com/technet/pro...ads/books.mspx
Books Online for SQL Server 2000 at
http://www.microsoft.com/sql/prodinf...ons/books.mspx
Jun 4 '06 #4
On Sun, 4 Jun 2006 16:22:48 +0000 (UTC), in
comp.databases.ms-sqlserver Erland Sommarskog <es****@sommarskog.se>
<Xn**********************@127.0.0.1> wrote:
| Jeff North (jn******@yahoo.com.au) writes:
| > On Sat, 3 Jun 2006 17:34:14 +0000 (UTC), in
| > comp.databases.ms-sqlserver Erland Sommarskog <es****@sommarskog.se>
| ><Xn**********************@127.0.0.1> wrote:
| >>| I can't really say what might be the problem
| >>| in this case, but I guess that if you add triggers into the mix, there
| >>| can be intersting results.
| >
| > No triggers at present but it looks as though triggers might be the
| > only option.
|
| What I wanted to say that combination of cascading DRI (had it been
| permitted) and triggers in this case could have lead to interesting
| results.
I could well imagine what sort of 'problems' could arise :-)
| And since a trigger could be added later, my suspicion that the
| mere possibility is enough to disallow the multiple cascade path.

---------------------------------------------------------------
jn******@yourpantsyahoo.com.au : Remove your pants to reply
---------------------------------------------------------------
Jun 4 '06 #5
Have you considered a relational design? It would have actual keys of
a proper data type and some research about standards? Do you really
know anyone with a first_name that is VARCHAR(100)? Why did you think
that IDENTITY can ever, ever be a key? And a key with a DEFAULT?
Defaults are for attributes which can have multiple occurrences of
values. And why did think that you need a BIGINT so you can have more
users than the entire population of Earth?

Can you use the "Dictionary of Occupational Titles" for
Competencies? What research did you do?

Why is a user an attribute of a Competency? Only Fred can be a
carpenter? Why do you use bit flags in SQL?
CREATE TABLE Competencies
(dot_code CHAR(6) NOT NULL PRIMARY KEY,
dot_description VARCHAR(25) NOT NULL);

Shouldn't there be a user attribute for approval powers? You did not
show one.

CREATE TABLE Users
(user_id INTEGER NOT NULL PRIMARY KEY, -- needs research!
first_name VARCHAR(25) NOT NULL,
last_name VARCHAR(25) NOT NULL);
When I delete a competency record [sic] I need all references to this record [sic] to be deleted. When I delete a user I want to set the foreign key to zero (the record [sic] must remain on the database). <<


One of the first steps to learning to think in SQL is that a row and a
record are totally different. Until then, you will keep setting flags
(like your "foreign keys are set to zero" violation of 1NF).

You are trying to keep a history, so you need durations in the data
model.

CREATE TABLE Assignments
(user_id INTEGER NOT NULL
REFERENCES Users(user_id)
ON DELETE CASCADE
ON UPDATE CASCADE,
dot_code CHAR(6) NOT NULL
REFERENCES Competencies(dot_code)
ON UPDATE CASCADE,
assignment_date DATETIME
DEFAULT CURRENT_TIMESTAMP NOT NULL,
completion_date DATETIME
DEFAULT CURRENT_TIMESTAMP
CHECK (assignment_date < completion_date),
PRIMARY KEY (user_id, dot_code, assignment_date),
approving_user_id INTEGER NOT NULL
REFERENCES Users(user_id)
ON DELETE CASCADE
ON UPDATE CASCADE);

This is proper SQL, but SQL Server will not allow it. The product
worries about cycles in DRI.

One kludge might be to split out the approvers

CREATE TABLE Competencies
(dot_code CHAR(6) NOT NULL PRIMARY KEY,
dot_description VARCHAR(25) NOT NULL);

CREATE TABLE Users
(user_id INTEGER NOT NULL,
user_type CHAR(1) DEFAULT 'R' NOT NULL
CHECK (user_type IN ('R', 'A')), -- r= regular, a = approver
PRIMARY KEY (user_id, user_type),
first_name VARCHAR(25) NOT NULL,
last_name VARCHAR(25) NOT NULL);

CREATE TABLE Approvers
(user_id INTEGER NOT NULL,
user_type CHAR(1) NOT NULL
CHECK (user_type = 'A'),
PRIMARY KEY (user_id, user_type),
FOREIGN KEY (user_id, user_type)
REFERENCES Users (user_id, user_type)
ON DELETE CASCADE
ON UPDATE CASCADE);

CREATE TABLE RegularUsers
(user_id INTEGER NOT NULL,
user_type CHAR(1) NOT NULL
CHECK (user_type = 'R'),
PRIMARY KEY (user_id, user_type),
FOREIGN KEY (user_id, user_type)
REFERENCES Users (user_id, user_type)
ON DELETE CASCADE
ON UPDATE CASCADE);

CREATE TABLE Assignments
(user_id INTEGER NOT NULL,
user_type CHAR(1) NOT NULL CHECK (user_type = 'R')
FOREIGN KEY (iser_id, user_type)
REFERENCES RegularUsers(user_id, user_type)
ON DELETE CASCADE
ON UPDATE CASCADE,
dot_code CHAR(6) NOT NULL
REFERENCES Competencies(dot_code)
ON UPDATE CASCADE,
assignment_date DATETIME
DEFAULT CURRENT_TIMESTAMP NOT NULL,
completion_date DATETIME
DEFAULT CURRENT_TIMESTAMP
CHECK (assignment_date < completion_date),
PRIMARY KEY (user_id, dot_code, assignment_date),
approving_user_id INTEGER NOT NULL,
user_type CHAR(1) NOT NULL CHECK (user_type = 'A')
FOREIGN KEY (user_id, user_type)
REFERENCES ApprovingUsers(user_id, user_type)
ON DELETE CASCADE
ON UPDATE CASCADE);

Jun 5 '06 #6
On 5 Jun 2006 10:52:35 -0700, in comp.databases.ms-sqlserver
"--CELKO--" <jc*******@earthlink.net>
<11**********************@i39g2000cwa.googlegroups .com> wrote:
| Have you considered a relational design? It would have actual keys of
| a proper data type and some research about standards? Do you really
| know anyone with a first_name that is VARCHAR(100)? Why did you think
| that IDENTITY can ever, ever be a key? And a key with a DEFAULT?
| Defaults are for attributes which can have multiple occurrences of
| values. And why did think that you need a BIGINT so you can have more
| users than the entire population of Earth?
Please don't jump to unnecassary, and wrong, conclussions.
I'm converting the database from mySQL4.0.21 to MSSQL therefore the
schema hasn't been fully optimised.
| Can you use the "Dictionary of Occupational Titles" for
| Competencies? What research did you do?
Again, you've seen 3 partial tables and jump to unnecessary
conclusions.
| Why is a user an attribute of a Competency? Only Fred can be a
| carpenter? Why do you use bit flags in SQL?
They, bit flags, are the most appropriate type for true/false or
yes/no or in/out data fields, yes?
| CREATE TABLE Competencies
| (dot_code CHAR(6) NOT NULL PRIMARY KEY,
| dot_description VARCHAR(25) NOT NULL);
|
| Shouldn't there be a user attribute for approval powers? You did not
| show one.
|
| CREATE TABLE Users
| (user_id INTEGER NOT NULL PRIMARY KEY, -- needs research!
| first_name VARCHAR(25) NOT NULL,
| last_name VARCHAR(25) NOT NULL);
Again, you're jumping to wrong conclusions.
The usr_info table is for registered users that can add, delete and
modify data. I need to track who has done what as part of the business
rules for the application (as can be seen by the ApprovedBy and
LockedBy fields).
| >> When I delete a competency record [sic] I need all references to this record [sic] to be deleted. When I delete a user I want to set the foreign key to zero (the record [sic] must remain on the database). <<
|
| One of the first steps to learning to think in SQL is that a row and a
| record are totally different.
Please explain this further.
| Until then, you will keep setting flags
| (like your "foreign keys are set to zero" violation of 1NF).
|

I've snipped your code but will study it further.
---------------------------------------------------------------
jn******@yourpantsyahoo.com.au : Remove your pants to reply
---------------------------------------------------------------
Jun 5 '06 #7

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

0
by: Sharon Cowling | last post by:
Hi, my problem is this: I have a table called faps_key the unique identifier being key_code: taupo=# \d faps_key Table "faps_key" Column | Type | Modifiers...
1
by: Grant McLean | last post by:
Hi First a simple question ... I have a table "access_log" that has foreign keys "app_id" and "app_user_id" that reference the "application_type" and "app_user" tables. When I insert into...
7
by: Jimmie H. Apsey | last post by:
Referential Integrity on one of our production tables seems to have been lost. I am running Postgres 7.1.3 embedded within Red Hat kernel-2.4.9-e.49. Within that I have a table with referential...
5
by: Geisler, Jim | last post by:
So, as far as I know, PostgreSQL does not have any way of verifying the loss of referential integrity. Are there any recommended methods or utilities for checking referential integrity in a...
1
by: HGT | last post by:
Hello all, I am currently on a project which the source data come into the databases is always dirty (not surprisingly); however, due to the design of the database, it is very difficult to...
6
by: heyvinay | last post by:
I have transaction table where the rows entered into the transaction can come a result of changes that take place if four different tables. So the situation is as follows: Transaction Table...
3
by: moskie | last post by:
Is there a way to run an alter table statement that adds a constraint for a foreign key, but does *not* check the existing data for refrential integrity? I'm essentially looking for the equivalent...
6
by: CPAccess | last post by:
How do I maintain referential integrity between a main form and a subform, each based upon different (but joined with integrity enforced) table? Here's the situation: I have two tables:...
3
by: Wayne | last post by:
I've inadvertently placed this post in another similar newgroup, and I apologise if you get it twice. I'm building a database that consists of frontend and backend. Some of the lookup tables...
2
by: ApexData | last post by:
Access2000, using a continuous form. I’m getting a message that say “you cannot add or change a record because a related record is required in table Employee”. This occurs in all my combobox...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.