Showing posts with label cascade. Show all posts
Showing posts with label cascade. Show all posts

Friday, March 9, 2012

Problem when adding cascade actions to a relationship

Hello everyone,

I wanted to change a relationship in a database in order for it to have a cascading effect on update and on delete in order to preserve the data integrity. The problem is that when I click the save button I get the following error message:

'Role (Application)' table saved successfully
'Usergroup_Role (Security)' table
- Unable to create relationship 'FK_Usergroup_Role_RoleId_Application_Role_Id'.
Introducing FOREIGN KEY constraint 'FK_Usergroup_Role_RoleId_Application_Role_Id' on table 'Usergroup_Role' may cause cycles or multiple cascade paths. Specify ON DELETE NO ACTION or ON UPDATE NO ACTION, or modify other FOREIGN KEY constraints.
Could not create constraint. See previous errors.

Any suggestion on how can I fix this? For a better understanding of the real problem I've uploaded a picture of the tables diagram.Here's the link

Best regards.

Instead of using a cascade, why not either write the delete into your stored procedure or usea logical delete flag?

|||

TATWORTH:

Instead of using a cascade, why not either write the delete into your stored procedure or usea logical delete flag?

Thanks for your reply Tatworth. It's only because that would make me have half the app with cascade and the other half hand coded. Before I consider that solution I'd much rather understand why this error is being returned and to know if there's any design change I can put in place to fix it.

Problem when adding cascade actions to a relationship

Hello everyone,

I wanted to change a relationship in a database in order for it to have a cascading effect on update and on delete in order to preserve the data integrity. The problem is that when I click the save button I get the following error message:

'Role (Application)' table saved successfully
'Usergroup_Role (Security)' table
- Unable to create relationship 'FK_Usergroup_Role_RoleId_Application_Role_Id'.
Introducing FOREIGN KEY constraint 'FK_Usergroup_Role_RoleId_Application_Role_Id' on table 'Usergroup_Role' may cause cycles or multiple cascade paths. Specify ON DELETE NO ACTION or ON UPDATE NO ACTION, or modify other FOREIGN KEY constraints.
Could not create constraint. See previous errors.

Any suggestion on how can I fix this? For a better understanding of the real problem I've uploaded a picture of the tables diagram. Here's the link

Best regards.

Think about it. If you happen to delete a row in Base table, it trickle downs the cascade deletes in two ways. One thru Role table and the other UserGroup table. so its setting up the cascade deletes in two separate paths and they finally end up deleting data in UserGroup_Role table from two paths. You need to put some more thought to the model before setting up the relationships.

As a different matter, you need to work on the naming standards also. Use good names for the column so that it describes the entity attributes. Take Id column, its very to hard to know which Id you are referring to. Name the columns as RoleID, BaseID, UserGroupID, RoleCategoryID etc...
|||

Thanks for your reply Sankar,

Yes, I understand what your are saying but how do you suggest me to do this in order to preserve the database integrity when a Role is deleted? I was trying to enforce this through the use of a cascade effect, thus preventing the existence of orphan rows in the [Security].[Usergroup_Role] table. An alternative would be to create a trigger, or something like that, to do enforce this programmatically.

I’m still trying to learn the best way to solve this kind of issues in SQL Server.

As for your observation regarding the Id columns: thanks, that’s something I can certainly change.

Best regards.

|||

Whenever you have cyclic relationships between tables then as a common rule, you are either missing something or overdoing something. As we don't know the business rules wrt the model, we can only guess. Only you can make the judgement.

Ask yourself, does UserGroupID depend on applicationID, how and why?

What is the relationship between UserGroup and Role? and let us know how you got over this.

|||

Prolly, I'm just failing to see exactly what is overdone or missing. The rules are quite simple in fact.

Each application [Application].[Base] can have a variable number of Roles, for example Delete Employee. Each of the roles will have to be associated with the application to which they belong, which is represented by the column [ApplicationId] in the [Application].[Role] table. Furthermore, they also have to belong one (and only one) role Category from the [Application].[Role_Category] table. This relation is represented by the [CategoryId] column in the [Application].[Role] table.

In order to define who has access to what each application will define a variable number of usergroups through the [Security].[Usergroup] table. Since the usergroup is associated with an application (because they belong to it and are only to be used within it) this relation is enforced by the [ApplicationId] column in the [Security].[Usergroup].

Since the relation between usergroups and roles is many-to-many there was the need to create a link table [Security].[Usergroup_Roles] which makes the association of the roles that each usergroup has, or hasn't, access to.

Furthermore, there's the need to enforce data integrety in the following way:

If an application is deleted from the [Application].[Base] all of its usergroups, and consequently the roles that usergroup is associated with, must be deleted from the tables [Security].[Usergroup] and [Security].[Usergroup_Role] respectively.

The next integrety rule states that the roles associated with an application [Application.Role] must also be deleted should the application, to which they belong to, get deleted in the [Application].[Base]. That, by itself, isn't a problem. The cascading relation between the columns [Application].[Role].[ApplicationId] and [Application].[Base].[Id] takes care of that for us just fine.

So far so good!

The problem occurs when I try to enforce the 3rd integrety rule: Should an application role be deleted from the [Application].[Role] table, that action must be enforced in the [Security].[Usergroup_Role], as there can't be an allow / deny relation to an inexisting role. The creation of a cascading relation between [Security].[Usergroup_Role].[RoleId] and [Application].[Role].[Id] causes the multiple path error.

I know I could solve this with a trigger in the [Application].[Role] table that enforces the integrety after delete using the virtual DELETED table. That's infact what's in place at the moment. Thus, leaving me with only one question: is there any design change I can make to enforce all the integrety rules through cascading relations, instead of using programmatic solutions (triggers or otherwise)?

|||

I was reading this and thought i would chime in. I checked out the ERD and also agree that it looked a bit cyclical. When the ERD starts to look like a circle, I always recommend going back to the drawing board as it can lead to fictitious data being generated via queries.

I know this doesn't exactly meet your needs as detailed above, however, if you can come up with commonly conceived roles and groups, you may find that you can reuse them in multiple applications.

Not knowing your full details, I thought I would propose my solution anyways. I would have made a different design choice.

Your major objects appear to be the Base Application, User Groups and Roles. I believe you are trying to capture the the relationship in an inappropriate way. I would recommend having your 3 core tables each have a one-to-many relationship with a new link table which you may call ApplicationUserGroupRole. This would be uniquely indexed by a super key of the User Group, Role, and Application tables. (keeping the role_category table as is) Dropping the exising Usergroup_Role table.

This would allow you to capture the relationships of what User Group has which roles in which applications. I am not a believer of deleting historical security access information, so I would recommend having an Active Bit column or Active/Inactive DateTime fields to indicate when a specific user group has role rights in a specific application.

It wouldn't force the deletion of roles, etc... but a cascading delete should force the deletion of the link history table. (still a bad idea I think)

|||

Hello asjev1, I'm glad you dropped by Wink

I understand your design implementation, however I believe it doesn't meet our requirements. For instance, in your design the usergroups and the roles can exist even if the application they belong to is no longer there, only enforcing such integrety in the ApplicationUsergroupRole table. Ultimately this would mean that you would, eventualy, and if I understood correctly, end up with a number of usergroups and roles, in their respective core tables, that are no longer in use (as in for good).

Regarding the historical data I'm doing this a bit differently that what you might expect. The history, in this particular case, works this way: when an object (say a datarow) is changed it's shipped in XML to a log system. That XML contains all sort of informations, including the object in its original state prior to the change. All the history is monitored 24/7 by the staff of the company.

|||

Triggers are evil! But they may do the trick in this instance, depending on the load placed on your server. If the server isn't being over utilized nor does the plan call for a huge increase, then triggers are a great solution. But if you want cascading deletes, you have to get away from the cyclical pattern.

Good luck! Let us know how you solve this!

asjev1

|||Yes, indeed. Don't suppose you have a suggestion to fix the problem I pointed in your design.|||

If I understand your largest concern, that you would like all groups and roles associated with an application deleted once an application is removed, you could place an instead of delete trigger on the application table per the design i mentioned previously. The primary key of the application table can be caught in the temporary deleted table available in the trigger.

You could then do something like this:

CREATE TABLE TempTable

(ApplicationID,

RoleID,

GroupID)

1. Select associated records into temp table

SELECT ApplicationID,RoleId, GroupID

From ApplicationUserGroupRole

where ApplicationId=(SELECT ApplicationID from deleted);

2. delete link table records

Delete from ApplicationUserGroupRole

Where ApplicationId in (Select ApplicationID from deleted);

3. delete from role and group and application tables

Delete from ApplicationRole

Where RoleID in (select roleID from TempTable);

Delete from ApplicationGroup

Where GroupID in (select groupID from TempTable);

Delete from Application

where applicationID in (select applicationID from TempTable)

4. Clean up temp table

Drop Table TempTable

The net effect is:

1. Copy needed records into temporary table

2. Drop link table record (ApplicationUserGroupRole).

3. Drop Application/Role/Group records

4. Clean up

Hope it helps.

|||

Thanks both of you for your help.

Problem when adding cascade actions to a relationship

Hello everyone,

I wanted to change a relationship in a database in order for it to have a cascading effect on update and on delete in order to preserve the data integrity. The problem is that when I click the save button I get the following error message:

'Role (Application)' table saved successfully
'Usergroup_Role (Security)' table
- Unable to create relationship 'FK_Usergroup_Role_RoleId_Application_Role_Id'.
Introducing FOREIGN KEY constraint 'FK_Usergroup_Role_RoleId_Application_Role_Id' on table 'Usergroup_Role' may cause cycles or multiple cascade paths. Specify ON DELETE NO ACTION or ON UPDATE NO ACTION, or modify other FOREIGN KEY constraints.
Could not create constraint. See previous errors.

Any suggestion on how can I fix this? For a better understanding of the real problem I've uploaded a picture of the tables diagram. Here's the link

Best regards.

Think about it. If you happen to delete a row in Base table, it trickle downs the cascade deletes in two ways. One thru Role table and the other UserGroup table. so its setting up the cascade deletes in two separate paths and they finally end up deleting data in UserGroup_Role table from two paths. You need to put some more thought to the model before setting up the relationships.

As a different matter, you need to work on the naming standards also. Use good names for the column so that it describes the entity attributes. Take Id column, its very to hard to know which Id you are referring to. Name the columns as RoleID, BaseID, UserGroupID, RoleCategoryID etc...
|||

Thanks for your reply Sankar,

Yes, I understand what your are saying but how do you suggest me to do this in order to preserve the database integrity when a Role is deleted? I was trying to enforce this through the use of a cascade effect, thus preventing the existence of orphan rows in the [Security].[Usergroup_Role] table. An alternative would be to create a trigger, or something like that, to do enforce this programmatically.

I’m still trying to learn the best way to solve this kind of issues in SQL Server.

As for your observation regarding the Id columns: thanks, that’s something I can certainly change.

Best regards.

|||

Whenever you have cyclic relationships between tables then as a common rule, you are either missing something or overdoing something. As we don't know the business rules wrt the model, we can only guess. Only you can make the judgement.

Ask yourself, does UserGroupID depend on applicationID, how and why?

What is the relationship between UserGroup and Role? and let us know how you got over this.

|||

Prolly, I'm just failing to see exactly what is overdone or missing. The rules are quite simple in fact.

Each application [Application].[Base] can have a variable number of Roles, for example Delete Employee. Each of the roles will have to be associated with the application to which they belong, which is represented by the column [ApplicationId] in the [Application].[Role] table. Furthermore, they also have to belong one (and only one) role Category from the [Application].[Role_Category] table. This relation is represented by the [CategoryId] column in the [Application].[Role] table.

In order to define who has access to what each application will define a variable number of usergroups through the [Security].[Usergroup] table. Since the usergroup is associated with an application (because they belong to it and are only to be used within it) this relation is enforced by the [ApplicationId] column in the [Security].[Usergroup].

Since the relation between usergroups and roles is many-to-many there was the need to create a link table [Security].[Usergroup_Roles] which makes the association of the roles that each usergroup has, or hasn't, access to.

Furthermore, there's the need to enforce data integrety in the following way:

If an application is deleted from the [Application].[Base] all of its usergroups, and consequently the roles that usergroup is associated with, must be deleted from the tables [Security].[Usergroup] and [Security].[Usergroup_Role] respectively.

The next integrety rule states that the roles associated with an application [Application.Role] must also be deleted should the application, to which they belong to, get deleted in the [Application].[Base]. That, by itself, isn't a problem. The cascading relation between the columns [Application].[Role].[ApplicationId] and [Application].[Base].[Id] takes care of that for us just fine.

So far so good!

The problem occurs when I try to enforce the 3rd integrety rule: Should an application role be deleted from the [Application].[Role] table, that action must be enforced in the [Security].[Usergroup_Role], as there can't be an allow / deny relation to an inexisting role. The creation of a cascading relation between [Security].[Usergroup_Role].[RoleId] and [Application].[Role].[Id] causes the multiple path error.

I know I could solve this with a trigger in the [Application].[Role] table that enforces the integrety after delete using the virtual DELETED table. That's infact what's in place at the moment. Thus, leaving me with only one question: is there any design change I can make to enforce all the integrety rules through cascading relations, instead of using programmatic solutions (triggers or otherwise)?

|||

I was reading this and thought i would chime in. I checked out the ERD and also agree that it looked a bit cyclical. When the ERD starts to look like a circle, I always recommend going back to the drawing board as it can lead to fictitious data being generated via queries.

I know this doesn't exactly meet your needs as detailed above, however, if you can come up with commonly conceived roles and groups, you may find that you can reuse them in multiple applications.

Not knowing your full details, I thought I would propose my solution anyways. I would have made a different design choice.

Your major objects appear to be the Base Application, User Groups and Roles. I believe you are trying to capture the the relationship in an inappropriate way. I would recommend having your 3 core tables each have a one-to-many relationship with a new link table which you may call ApplicationUserGroupRole. This would be uniquely indexed by a super key of the User Group, Role, and Application tables. (keeping the role_category table as is) Dropping the exising Usergroup_Role table.

This would allow you to capture the relationships of what User Group has which roles in which applications. I am not a believer of deleting historical security access information, so I would recommend having an Active Bit column or Active/Inactive DateTime fields to indicate when a specific user group has role rights in a specific application.

It wouldn't force the deletion of roles, etc... but a cascading delete should force the deletion of the link history table. (still a bad idea I think)

|||

Hello asjev1, I'm glad you dropped by Wink

I understand your design implementation, however I believe it doesn't meet our requirements. For instance, in your design the usergroups and the roles can exist even if the application they belong to is no longer there, only enforcing such integrety in the ApplicationUsergroupRole table. Ultimately this would mean that you would, eventualy, and if I understood correctly, end up with a number of usergroups and roles, in their respective core tables, that are no longer in use (as in for good).

Regarding the historical data I'm doing this a bit differently that what you might expect. The history, in this particular case, works this way: when an object (say a datarow) is changed it's shipped in XML to a log system. That XML contains all sort of informations, including the object in its original state prior to the change. All the history is monitored 24/7 by the staff of the company.

|||

Triggers are evil! But they may do the trick in this instance, depending on the load placed on your server. If the server isn't being over utilized nor does the plan call for a huge increase, then triggers are a great solution. But if you want cascading deletes, you have to get away from the cyclical pattern.

Good luck! Let us know how you solve this!

asjev1

|||Yes, indeed. Don't suppose you have a suggestion to fix the problem I pointed in your design.|||

If I understand your largest concern, that you would like all groups and roles associated with an application deleted once an application is removed, you could place an instead of delete trigger on the application table per the design i mentioned previously. The primary key of the application table can be caught in the temporary deleted table available in the trigger.

You could then do something like this:

CREATE TABLE TempTable

(ApplicationID,

RoleID,

GroupID)

1. Select associated records into temp table

SELECT ApplicationID,RoleId, GroupID

From ApplicationUserGroupRole

where ApplicationId=(SELECT ApplicationID from deleted);

2. delete link table records

Delete from ApplicationUserGroupRole

Where ApplicationId in (Select ApplicationID from deleted);

3. delete from role and group and application tables

Delete from ApplicationRole

Where RoleID in (select roleID from TempTable);

Delete from ApplicationGroup

Where GroupID in (select groupID from TempTable);

Delete from Application

where applicationID in (select applicationID from TempTable)

4. Clean up temp table

Drop Table TempTable

The net effect is:

1. Copy needed records into temporary table

2. Drop link table record (ApplicationUserGroupRole).

3. Drop Application/Role/Group records

4. Clean up

Hope it helps.

|||

Thanks both of you for your help.

Monday, February 20, 2012

Problem using DRI with CASCADE action.

(SQL Server 2000, SP3)
Hello all!
I am trying to use ERwin to create a new schema. In the past, because of limitations with
SQL Server's declarative referential integrity (DRI), I typically did all my RI through
triggers. I thought I'd take the plunge and try using DRI with a
Parent-Cascade/Child-Restrict paradigm.
When I generate the script, I get the following:
CREATE TABLE amContainer (
ContainerId int IDENTITY(1, 1),
ParentContainerId int NULL,
TypeContainerId int NOT NULL,
CONSTRAINT XPKamContainer
PRIMARY KEY (ContainerId)
)
go
CREATE TABLE amTypeContainer (
TypeContainerId int IDENTITY(1, 1),
Name varchar(255) NOT NULL,
CONSTRAINT XPKamTypeContainer
PRIMARY KEY (TypeContainerId)
)
go
ALTER TABLE amContainer
ADD CONSTRAINT R_3
FOREIGN KEY (TypeContainerId)
REFERENCES amTypeContainer
ON DELETE CASCADE
ON UPDATE CASCADE
go
ALTER TABLE amContainer
ADD CONSTRAINT R_1
FOREIGN KEY (ParentContainerId)
REFERENCES amContainer
ON UPDATE CASCADE
go
I'm getting an error on R_1 (that last ALTER TABLE command):
Server: Msg 1785, Level 16, State 1, Line 3
Introducing FOREIGN KEY constraint 'R_1' on table 'amContainer' may cause cycles or
multiple cascade paths. Specify ON DELETE NO ACTION or ON UPDATE NO ACTION, or modify
other FOREIGN KEY constraints.
Server: Msg 1750, Level 16, State 1, Line 3
Could not create constraint. See previous errors.
Is this not possible with DRI? Do I need to resort to triggers to apply what I want?
Thanks for any help you can provide!
John PetersonThis is a multi-part message in MIME format.
--=_NextPart_000_015B_01C3618E.3E6B8530
Content-Type: text/plain;
charset="Windows-1252"
Content-Transfer-Encoding: quoted-printable
You cannot use DRI for cascades on a self-referencing table. For this, =you will need a trigger.
-- Tom
---
Thomas A. Moreau, BSc, PhD, MCSE, MCDBA
SQL Server MVP
Columnist, SQL Server Professional
Toronto, ON Canada
www.pinnaclepublishing.com/sql
"John Peterson" <j0hnp@.comcast.net> wrote in message =news:etENJ7aYDHA.2572@.TK2MSFTNGP09.phx.gbl...
(SQL Server 2000, SP3)
Hello all!
I am trying to use ERwin to create a new schema. In the past, because =of limitations with
SQL Server's declarative referential integrity (DRI), I typically did =all my RI through
triggers. I thought I'd take the plunge and try using DRI with a
Parent-Cascade/Child-Restrict paradigm.
When I generate the script, I get the following:
CREATE TABLE amContainer (
ContainerId int IDENTITY(1, 1),
ParentContainerId int NULL,
TypeContainerId int NOT NULL,
CONSTRAINT XPKamContainer
PRIMARY KEY (ContainerId)
)
go
CREATE TABLE amTypeContainer (
TypeContainerId int IDENTITY(1, 1),
Name varchar(255) NOT NULL,
CONSTRAINT XPKamTypeContainer
PRIMARY KEY (TypeContainerId)
)
go
ALTER TABLE amContainer
ADD CONSTRAINT R_3
FOREIGN KEY (TypeContainerId)
REFERENCES amTypeContainer
ON DELETE CASCADE
ON UPDATE CASCADE
go
ALTER TABLE amContainer
ADD CONSTRAINT R_1
FOREIGN KEY (ParentContainerId)
REFERENCES amContainer
ON UPDATE CASCADE
go
I'm getting an error on R_1 (that last ALTER TABLE command):
Server: Msg 1785, Level 16, State 1, Line 3
Introducing FOREIGN KEY constraint 'R_1' on table 'amContainer' may =cause cycles or
multiple cascade paths. Specify ON DELETE NO ACTION or ON UPDATE NO =ACTION, or modify
other FOREIGN KEY constraints.
Server: Msg 1750, Level 16, State 1, Line 3
Could not create constraint. See previous errors.
Is this not possible with DRI? Do I need to resort to triggers to apply =what I want?
Thanks for any help you can provide!
John Peterson
--=_NextPart_000_015B_01C3618E.3E6B8530
Content-Type: text/html;
charset="Windows-1252"
Content-Transfer-Encoding: quoted-printable
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
&

You cannot use DRI for cascades on a self-referencing table. For this, you will need a =trigger.
-- Tom
---T=homas A. Moreau, BSc, PhD, MCSE, MCDBASQL Server MVPColumnist, SQL =Server ProfessionalToronto, ON Canadahttp://www.pinnaclepublishing.com/sql">www.pinnaclepublishing.com=/sql
"John Peterson" wrote in =message news:etENJ7aYDHA.2572=@.TK2MSFTNGP09.phx.gbl...(SQL Server 2000, SP3)Hello all!I am trying to use ERwin to =create a new schema. In the past, because of limitations withSQL =Server's declarative referential integrity (DRI), I typically did all my RI throughtriggers. I thought I'd take the plunge and try using =DRI with aParent-Cascade/Child-Restrict paradigm.When I generate the =script, I get the following:CREATE TABLE amContainer ( ContainerId int IDENTITY(1, 1), ParentContainerId int NULL, TypeContainerId int NOT NULL, CONSTRAINT XPKamContainer &=nbsp; PRIMARY KEY (ContainerId))goCREATE TABLE amTypeContainer =( TypeContainerId int IDENTITY(1, 1), Name &nb=sp; varchar(255) NOT NULL, =CONSTRAINT XPKamTypeContainer &nb=sp; PRIMARY KEY (TypeContainerId))goALTER TABLE amContainer ADD CONSTRAINT R_3 = FOREIGN KEY (TypeContainerId) &nbs=p;  =; REFERENCES amTypeContainer = &=nbsp; ON DELETE CASCADE &n=bsp; &nb=sp; ON UPDATE CASCADEgoALTER TABLE amContainer ADD CONSTRAINT R_1 = FOREIGN KEY (ParentContainerId) &n=bsp; &nb=sp; REFERENCES amContainer &nbs=p;  =; ON UPDATE CASCADEgoI'm getting an error on R_1 (that =last ALTER TABLE command):Server: Msg 1785, Level 16, State 1, Line 3Introducing FOREIGN KEY constraint 'R_1' on table 'amContainer' may =cause cycles ormultiple cascade paths. Specify ON DELETE NO ACTION or ON =UPDATE NO ACTION, or modifyother FOREIGN KEY constraints.Server: Msg 1750, =Level 16, State 1, Line 3Could not create constraint. See previous errors.Is this not possible with DRI? Do I need to resort =to triggers to apply what I want?Thanks for any help you can provide!John Peterson

--=_NextPart_000_015B_01C3618E.3E6B8530--|||This is a multi-part message in MIME format.
--=_NextPart_000_002D_01C36176.F30B8700
Content-Type: multipart/alternative;
boundary="--=_NextPart_001_002E_01C36176.F30B8700"
--=_NextPart_001_002E_01C36176.F30B8700
Content-Type: text/plain;
charset="Windows-1252"
Content-Transfer-Encoding: quoted-printable
Tom, I'm still having trouble with other aspects of DRI. Please see the =attached DDL -- this time it's with my R_8 relationship. I don't quite ="grok" why this is problematic. (It's not as clear-cut as a =self-referencing table.)
Any additional help you can provide would be greatly appreciated!
John Peterson
"John Peterson" <j0hnp@.comcast.net> wrote in message =news:%23BK4wDbYDHA.440@.tk2msftngp13.phx.gbl...
Thanks, Tom! Maybe I can "mix and match" and only use triggers where =necessary.
"Tom Moreau" <tom@.dont.spam.me.cips.ca> wrote in message =news:OPg2l$aYDHA.1640@.TK2MSFTNGP10.phx.gbl...
You cannot use DRI for cascades on a self-referencing table. For =this, you will need a trigger.
-- Tom
---
Thomas A. Moreau, BSc, PhD, MCSE, MCDBA
SQL Server MVP
Columnist, SQL Server Professional
Toronto, ON Canada
www.pinnaclepublishing.com/sql
"John Peterson" <j0hnp@.comcast.net> wrote in message =news:etENJ7aYDHA.2572@.TK2MSFTNGP09.phx.gbl...
(SQL Server 2000, SP3)
Hello all!
I am trying to use ERwin to create a new schema. In the past, =because of limitations with
SQL Server's declarative referential integrity (DRI), I typically =did all my RI through
triggers. I thought I'd take the plunge and try using DRI with a
Parent-Cascade/Child-Restrict paradigm.
When I generate the script, I get the following:
CREATE TABLE amContainer (
ContainerId int IDENTITY(1, 1),
ParentContainerId int NULL,
TypeContainerId int NOT NULL,
CONSTRAINT XPKamContainer
PRIMARY KEY (ContainerId)
)
go
CREATE TABLE amTypeContainer (
TypeContainerId int IDENTITY(1, 1),
Name varchar(255) NOT NULL,
CONSTRAINT XPKamTypeContainer
PRIMARY KEY (TypeContainerId)
)
go
ALTER TABLE amContainer
ADD CONSTRAINT R_3
FOREIGN KEY (TypeContainerId)
REFERENCES amTypeContainer
ON DELETE CASCADE
ON UPDATE CASCADE
go
ALTER TABLE amContainer
ADD CONSTRAINT R_1
FOREIGN KEY (ParentContainerId)
REFERENCES amContainer
ON UPDATE CASCADE
go
I'm getting an error on R_1 (that last ALTER TABLE command):
Server: Msg 1785, Level 16, State 1, Line 3
Introducing FOREIGN KEY constraint 'R_1' on table 'amContainer' may =cause cycles or
multiple cascade paths. Specify ON DELETE NO ACTION or ON UPDATE NO =ACTION, or modify
other FOREIGN KEY constraints.
Server: Msg 1750, Level 16, State 1, Line 3
Could not create constraint. See previous errors.
Is this not possible with DRI? Do I need to resort to triggers to =apply what I want?
Thanks for any help you can provide!
John Peterson
--=_NextPart_001_002E_01C36176.F30B8700
Content-Type: text/html;
charset="Windows-1252"
Content-Transfer-Encoding: quoted-printable
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
&

Tom, I'm still having trouble with =other aspects of DRI. Please see the attached DDL -- this time it's with my R_8 relationship. I don't quite "grok" why this is problematic. =(It's not as clear-cut as a self-referencing table.)
Any additional help you can provide =would be greatly appreciated!
John Peterson
"John Peterson" wrote in =message news:%23BK4wDbYDHA.4=40@.tk2msftngp13.phx.gbl...
Thanks, Tom! Maybe I can ="mix and match" and only use triggers where necessary.
"Tom Moreau" = wrote in message news:OPg2l$aYDHA.1640=@.TK2MSFTNGP10.phx.gbl...
You cannot use DRI for cascades on =a self-referencing table. For this, you will need a trigger.
-- Tom

=---T=homas A. Moreau, BSc, PhD, MCSE, MCDBASQL Server MVPColumnist, SQL =Server ProfessionalToronto, ON Canadahttp://www.pinnaclepublishing.com/sql">www.pinnaclepublishing.com=/sql


"John Peterson" wrote in =message news:etENJ7aYDHA.2572=@.TK2MSFTNGP09.phx.gbl...(SQL Server 2000, SP3)Hello all!I am trying to use ERwin =to create a new schema. In the past, because of limitations =withSQL Server's declarative referential integrity (DRI), I typically did =all my RI throughtriggers. I thought I'd take the plunge and try =using DRI with aParent-Cascade/Child-Restrict paradigm.When I =generate the script, I get the following:CREATE TABLE amContainer ( ContainerId =int IDENTITY(1, 1), ParentContainerId int NULL, TypeContainerId int NOT NULL, CONSTRAINT =XPKamContainer &=nbsp; PRIMARY KEY (ContainerId))goCREATE TABLE =amTypeContainer ( TypeContainerId int IDENTITY(1, 1), =Name &nb=sp; varchar(255) NOT NULL, =CONSTRAINT =XPKamTypeContainer &nb=sp; PRIMARY KEY (TypeContainerId))goALTER TABLE amContainer ADD CONSTRAINT =R_3 = FOREIGN KEY =(TypeContainerId) &nbs=p;  =; REFERENCES =amTypeContainer = &=nbsp; ON DELETE =CASCADE &n=bsp; &nb=sp; ON UPDATE CASCADEgoALTER TABLE amContainer ADD CONSTRAINT =R_1 = FOREIGN KEY =(ParentContainerId) &n=bsp; &nb=sp; REFERENCES =amContainer &nbs=p;  =; ON UPDATE CASCADEgoI'm getting an error on R_1 (that =last ALTER TABLE command):Server: Msg 1785, Level 16, State 1, =Line 3Introducing FOREIGN KEY constraint 'R_1' on table 'amContainer' =may cause cycles ormultiple cascade paths. Specify ON DELETE NO =ACTION or ON UPDATE NO ACTION, or modifyother FOREIGN KEY =constraints.Server: Msg 1750, Level 16, State 1, Line 3Could not create constraint. See =previous errors.Is this not possible with DRI? Do I need to =resort to triggers to apply what I want?Thanks for any help you can provide!John =Peterson

--=_NextPart_001_002E_01C36176.F30B8700--
--=_NextPart_000_002D_01C36176.F30B8700
Content-Type: text/plain;
name="Test.sql"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
filename="Test.sql"
CREATE TABLE amContainer (
ContainerId int IDENTITY(1, 1),
ParentContainerId int NULL,
TypeContainerId int NOT NULL,
CONSTRAINT XPKamContainer
PRIMARY KEY (ContainerId)
)
go
CREATE TABLE amMember (
MemberId int IDENTITY(1, 1),
ObjectId int NOT NULL,
ContainerId int NOT NULL,
TypeMemberAssociationId int NOT NULL,
CONSTRAINT XPKamMember
PRIMARY KEY (MemberId)
)
go
CREATE TABLE amObject (
ObjectId int IDENTITY(1, 1),
NativeObjectId uniqueidentifier NOT NULL,
TypeObjectId int NOT NULL,
CONSTRAINT XPKamObject
PRIMARY KEY (ObjectId)
)
go
CREATE TABLE amRights (
RightsId int IDENTITY(1, 1),
MemberId int NULL,
PartyObjectId int NULL,
Context varchar(255) NULL,
Rights varchar(255) NULL,
CONSTRAINT XPKamRights
PRIMARY KEY (RightsId)
)
go
CREATE TABLE amTypeContainer (
TypeContainerId int IDENTITY(1, 1),
Name varchar(255) NOT NULL,
CONSTRAINT XPKamTypeContainer
PRIMARY KEY (TypeContainerId)
)
go
CREATE TABLE amTypeMemberAssociation (
TypeMemberAssociationId int IDENTITY(1, 1),
Name varchar(255) NOT NULL,
Description varchar(255) NULL,
CONSTRAINT XPKamTypeMemberAssociation
PRIMARY KEY (TypeMemberAssociationId)
)
go
CREATE TABLE amTypeObject (
TypeObjectId int IDENTITY(1, 1),
Name varchar(255) NOT NULL,
TableSchema nvarchar(128) NULL,
TableName nvarchar(128) NULL,
TablePKColumn nvarchar(128) NULL,
CONSTRAINT XPKamTypeObject
PRIMARY KEY (TypeObjectId)
)
go
ALTER TABLE amContainer
ADD CONSTRAINT R_3
FOREIGN KEY (TypeContainerId)
REFERENCES amTypeContainer
ON DELETE CASCADE
ON UPDATE CASCADE
go
/*
ALTER TABLE amContainer
ADD CONSTRAINT R_1
FOREIGN KEY (ParentContainerId)
REFERENCES amContainer
ON UPDATE CASCADE
*/
go
ALTER TABLE amMember
ADD CONSTRAINT R_7
FOREIGN KEY (TypeMemberAssociationId)
REFERENCES amTypeMemberAssociation
ON DELETE CASCADE
ON UPDATE CASCADE
go
ALTER TABLE amMember
ADD CONSTRAINT R_6
FOREIGN KEY (ContainerId)
REFERENCES amContainer
ON DELETE CASCADE
ON UPDATE CASCADE
go
ALTER TABLE amMember
ADD CONSTRAINT R_5
FOREIGN KEY (ObjectId)
REFERENCES amObject
ON DELETE CASCADE
ON UPDATE CASCADE
go
ALTER TABLE amObject
ADD CONSTRAINT R_4
FOREIGN KEY (TypeObjectId)
REFERENCES amTypeObject
ON DELETE CASCADE
ON UPDATE CASCADE
go
ALTER TABLE amRights
ADD CONSTRAINT R_9
FOREIGN KEY (PartyObjectId)
REFERENCES amObject
ON DELETE CASCADE
ON UPDATE CASCADE
go
ALTER TABLE amRights
ADD CONSTRAINT R_8
FOREIGN KEY (MemberId)
REFERENCES amMember
ON DELETE CASCADE
ON UPDATE CASCADE
go
--=_NextPart_000_002D_01C36176.F30B8700--|||This is a multi-part message in MIME format.
--=_NextPart_000_01ED_01C36198.39729640
Content-Type: text/plain;
charset="Windows-1252"
Content-Transfer-Encoding: quoted-printable
This type of problem is not limited to a self-referencing table. =Rather, it occurs any time there is a circular dependency. Already, =there R_9 establishes a relationship between amRights and amObject. R_5 =establishes the relationship between amObject and amMember. By adding =R_8 - between amRights and amMember - you have completed the circle.
The way to see this is to look at the ER diagram. It looks like you =should remove R_9 and install R_8.
-- Tom
---
Thomas A. Moreau, BSc, PhD, MCSE, MCDBA
SQL Server MVP
Columnist, SQL Server Professional
Toronto, ON Canada
www.pinnaclepublishing.com/sql
"John Peterson" <j0hnp@.comcast.net> wrote in message =news:uFC7lGbYDHA.2448@.TK2MSFTNGP09.phx.gbl...
Tom, I'm still having trouble with other aspects of DRI. Please see the =attached DDL -- this time it's with my R_8 relationship. I don't quite ="grok" why this is problematic. (It's not as clear-cut as a =self-referencing table.)
Any additional help you can provide would be greatly appreciated!
John Peterson
"John Peterson" <j0hnp@.comcast.net> wrote in message =news:%23BK4wDbYDHA.440@.tk2msftngp13.phx.gbl...
Thanks, Tom! Maybe I can "mix and match" and only use triggers where =necessary.
"Tom Moreau" <tom@.dont.spam.me.cips.ca> wrote in message =news:OPg2l$aYDHA.1640@.TK2MSFTNGP10.phx.gbl...
You cannot use DRI for cascades on a self-referencing table. For =this, you will need a trigger.
-- Tom
---
Thomas A. Moreau, BSc, PhD, MCSE, MCDBA
SQL Server MVP
Columnist, SQL Server Professional
Toronto, ON Canada
www.pinnaclepublishing.com/sql
"John Peterson" <j0hnp@.comcast.net> wrote in message =news:etENJ7aYDHA.2572@.TK2MSFTNGP09.phx.gbl...
(SQL Server 2000, SP3)
Hello all!
I am trying to use ERwin to create a new schema. In the past, =because of limitations with
SQL Server's declarative referential integrity (DRI), I typically =did all my RI through
triggers. I thought I'd take the plunge and try using DRI with a
Parent-Cascade/Child-Restrict paradigm.
When I generate the script, I get the following:
CREATE TABLE amContainer (
ContainerId int IDENTITY(1, 1),
ParentContainerId int NULL,
TypeContainerId int NOT NULL,
CONSTRAINT XPKamContainer
PRIMARY KEY (ContainerId)
)
go
CREATE TABLE amTypeContainer (
TypeContainerId int IDENTITY(1, 1),
Name varchar(255) NOT NULL,
CONSTRAINT XPKamTypeContainer
PRIMARY KEY (TypeContainerId)
)
go
ALTER TABLE amContainer
ADD CONSTRAINT R_3
FOREIGN KEY (TypeContainerId)
REFERENCES amTypeContainer
ON DELETE CASCADE
ON UPDATE CASCADE
go
ALTER TABLE amContainer
ADD CONSTRAINT R_1
FOREIGN KEY (ParentContainerId)
REFERENCES amContainer
ON UPDATE CASCADE
go
I'm getting an error on R_1 (that last ALTER TABLE command):
Server: Msg 1785, Level 16, State 1, Line 3
Introducing FOREIGN KEY constraint 'R_1' on table 'amContainer' may =cause cycles or
multiple cascade paths. Specify ON DELETE NO ACTION or ON UPDATE NO =ACTION, or modify
other FOREIGN KEY constraints.
Server: Msg 1750, Level 16, State 1, Line 3
Could not create constraint. See previous errors.
Is this not possible with DRI? Do I need to resort to triggers to =apply what I want?
Thanks for any help you can provide!
John Peterson
--=_NextPart_000_01ED_01C36198.39729640
Content-Type: text/html;
charset="Windows-1252"
Content-Transfer-Encoding: quoted-printable
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
&

This type of problem is not limited to =a self-referencing table. Rather, it occurs any time there is a =circular dependency. Already, there R_9 establishes a relationship between =amRights and amObject. R_5 establishes the relationship between amObject =and amMember. By adding R_8 - between amRights and amMember - you have =completed the circle.
The way to see this is to look at the =ER diagram. It looks like you should remove R_9 and install =R_8.
-- Tom
---T=homas A. Moreau, BSc, PhD, MCSE, MCDBASQL Server MVPColumnist, SQL =Server ProfessionalToronto, ON Canadahttp://www.pinnaclepublishing.com/sql">www.pinnaclepublishing.com=/sql
"John Peterson" wrote in =message news:uFC7lGbYDHA.2448=@.TK2MSFTNGP09.phx.gbl...
Tom, I'm still having trouble with =other aspects of DRI. Please see the attached DDL -- this time it's with my R_8 relationship. I don't quite "grok" why this is problematic. =(It's not as clear-cut as a self-referencing table.)
Any additional help you can provide =would be greatly appreciated!
John Peterson
"John Peterson" wrote in =message news:%23BK4wDbYDHA.4=40@.tk2msftngp13.phx.gbl...
Thanks, Tom! Maybe I can ="mix and match" and only use triggers where necessary.
"Tom Moreau" = wrote in message news:OPg2l$aYDHA.1640=@.TK2MSFTNGP10.phx.gbl...
You cannot use DRI for cascades on =a self-referencing table. For this, you will need a trigger.
-- Tom

=---T=homas A. Moreau, BSc, PhD, MCSE, MCDBASQL Server MVPColumnist, SQL =Server ProfessionalToronto, ON Canadahttp://www.pinnaclepublishing.com/sql">www.pinnaclepublishing.com=/sql


"John Peterson" wrote in =message news:etENJ7aYDHA.2572=@.TK2MSFTNGP09.phx.gbl...(SQL Server 2000, SP3)Hello all!I am trying to use ERwin =to create a new schema. In the past, because of limitations =withSQL Server's declarative referential integrity (DRI), I typically did =all my RI throughtriggers. I thought I'd take the plunge and try =using DRI with aParent-Cascade/Child-Restrict paradigm.When I =generate the script, I get the following:CREATE TABLE amContainer ( ContainerId =int IDENTITY(1, 1), ParentContainerId int NULL, TypeContainerId int NOT NULL, CONSTRAINT =XPKamContainer &=nbsp; PRIMARY KEY (ContainerId))goCREATE TABLE =amTypeContainer ( TypeContainerId int IDENTITY(1, 1), =Name &nb=sp; varchar(255) NOT NULL, =CONSTRAINT =XPKamTypeContainer &nb=sp; PRIMARY KEY (TypeContainerId))goALTER TABLE amContainer ADD CONSTRAINT =R_3 = FOREIGN KEY =(TypeContainerId) &nbs=p;  =; REFERENCES =amTypeContainer = &=nbsp; ON DELETE =CASCADE &n=bsp; &nb=sp; ON UPDATE CASCADEgoALTER TABLE amContainer ADD CONSTRAINT =R_1 = FOREIGN KEY =(ParentContainerId) &n=bsp; &nb=sp; REFERENCES =amContainer &nbs=p;  =; ON UPDATE CASCADEgoI'm getting an error on R_1 (that =last ALTER TABLE command):Server: Msg 1785, Level 16, State 1, =Line 3Introducing FOREIGN KEY constraint 'R_1' on table 'amContainer' =may cause cycles ormultiple cascade paths. Specify ON DELETE NO =ACTION or ON UPDATE NO ACTION, or modifyother FOREIGN KEY =constraints.Server: Msg 1750, Level 16, State 1, Line 3Could not create constraint. See =previous errors.Is this not possible with DRI? Do I need to =resort to triggers to apply what I want?Thanks for any help you can provide!John =Peterson

--=_NextPart_000_01ED_01C36198.39729640--|||This is a multi-part message in MIME format.
--=_NextPart_000_0294_01C3619F.7B4E4FD0
Content-Type: text/plain;
charset="Windows-1252"
Content-Transfer-Encoding: quoted-printable
In that script you posted, just don't run the R_9 and do run the R_8.
-- Tom
---
Thomas A. Moreau, BSc, PhD, MCSE, MCDBA
SQL Server MVP
Columnist, SQL Server Professional
Toronto, ON Canada
www.pinnaclepublishing.com/sql
"John Peterson" <j0hnp@.comcast.net> wrote in message =news:OtZgG6bYDHA.212@.TK2MSFTNGP12.phx.gbl...
Tom, you're exactly right. I wanted the amRights table to either have a =relationship from the amMember table (which as a FK from amObject) or =the amObject table directly. See the attached ERwin diagram. Any =suggestions for how I might specify the RI in this case?
Thanks again for your time and your help!
John Peterson
"Tom Moreau" <tom@.dont.spam.me.cips.ca> wrote in message =news:%23FDYInbYDHA.1940@.TK2MSFTNGP10.phx.gbl...
This type of problem is not limited to a self-referencing table. =Rather, it occurs any time there is a circular dependency. Already, =there R_9 establishes a relationship between amRights and amObject. R_5 =establishes the relationship between amObject and amMember. By adding =R_8 - between amRights and amMember - you have completed the circle.
The way to see this is to look at the ER diagram. It looks like you =should remove R_9 and install R_8.
-- Tom
---
Thomas A. Moreau, BSc, PhD, MCSE, MCDBA
SQL Server MVP
Columnist, SQL Server Professional
Toronto, ON Canada
www.pinnaclepublishing.com/sql
"John Peterson" <j0hnp@.comcast.net> wrote in message =news:uFC7lGbYDHA.2448@.TK2MSFTNGP09.phx.gbl...
Tom, I'm still having trouble with other aspects of DRI. Please see =the attached DDL -- this time it's with my R_8 relationship. I don't =quite "grok" why this is problematic. (It's not as clear-cut as a =self-referencing table.)
Any additional help you can provide would be greatly appreciated!
John Peterson
"John Peterson" <j0hnp@.comcast.net> wrote in message =news:%23BK4wDbYDHA.440@.tk2msftngp13.phx.gbl...
Thanks, Tom! Maybe I can "mix and match" and only use triggers =where necessary.
"Tom Moreau" <tom@.dont.spam.me.cips.ca> wrote in message =news:OPg2l$aYDHA.1640@.TK2MSFTNGP10.phx.gbl...
You cannot use DRI for cascades on a self-referencing table. For =this, you will need a trigger.
-- Tom
---
Thomas A. Moreau, BSc, PhD, MCSE, MCDBA
SQL Server MVP
Columnist, SQL Server Professional
Toronto, ON Canada
www.pinnaclepublishing.com/sql
"John Peterson" <j0hnp@.comcast.net> wrote in message =news:etENJ7aYDHA.2572@.TK2MSFTNGP09.phx.gbl...
(SQL Server 2000, SP3)
Hello all!
I am trying to use ERwin to create a new schema. In the past, =because of limitations with
SQL Server's declarative referential integrity (DRI), I typically =did all my RI through
triggers. I thought I'd take the plunge and try using DRI with a
Parent-Cascade/Child-Restrict paradigm.
When I generate the script, I get the following:
CREATE TABLE amContainer (
ContainerId int IDENTITY(1, 1),
ParentContainerId int NULL,
TypeContainerId int NOT NULL,
CONSTRAINT XPKamContainer
PRIMARY KEY (ContainerId)
)
go
CREATE TABLE amTypeContainer (
TypeContainerId int IDENTITY(1, 1),
Name varchar(255) NOT NULL,
CONSTRAINT XPKamTypeContainer
PRIMARY KEY (TypeContainerId)
)
go
ALTER TABLE amContainer
ADD CONSTRAINT R_3
FOREIGN KEY (TypeContainerId)
REFERENCES amTypeContainer
ON DELETE CASCADE
ON UPDATE CASCADE
go
ALTER TABLE amContainer
ADD CONSTRAINT R_1
FOREIGN KEY (ParentContainerId)
REFERENCES amContainer
ON UPDATE CASCADE
go
I'm getting an error on R_1 (that last ALTER TABLE command):
Server: Msg 1785, Level 16, State 1, Line 3
Introducing FOREIGN KEY constraint 'R_1' on table 'amContainer' =may cause cycles or
multiple cascade paths. Specify ON DELETE NO ACTION or ON UPDATE =NO ACTION, or modify
other FOREIGN KEY constraints.
Server: Msg 1750, Level 16, State 1, Line 3
Could not create constraint. See previous errors.
Is this not possible with DRI? Do I need to resort to triggers to =apply what I want?
Thanks for any help you can provide!
John Peterson
--=_NextPart_000_0294_01C3619F.7B4E4FD0
Content-Type: text/html;
charset="Windows-1252"
Content-Transfer-Encoding: quoted-printable
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
&

In that script you posted, just don't =run the R_9 and do run the R_8.
-- Tom
---T=homas A. Moreau, BSc, PhD, MCSE, MCDBASQL Server MVPColumnist, SQL =Server ProfessionalToronto, ON Canadahttp://www.pinnaclepublishing.com/sql">www.pinnaclepublishing.com=/sql
"John Peterson" wrote in =message news:OtZgG6bYDHA.212@.T=K2MSFTNGP12.phx.gbl...
Tom, you're exactly right. I =wanted the amRights table to either have a relationship from the amMember table =(which as a FK from amObject) or the amObject table directly. See the attached =ERwin diagram. Any suggestions for how I might specify the RI in this case?
Thanks again for your time and your help!
John Peterson
"Tom Moreau" = wrote in message news:%23FDYInbYDHA.=1940@.TK2MSFTNGP10.phx.gbl...
This type of problem is not limited =to a self-referencing table. Rather, it occurs any time there is a =circular dependency. Already, there R_9 establishes a relationship =between amRights and amObject. R_5 establishes the relationship between =amObject and amMember. By adding R_8 - between amRights and amMember - =you have completed the circle.

The way to see this is to look at =the ER diagram. It looks like you should remove R_9 and install R_8.
-- Tom

=---T=homas A. Moreau, BSc, PhD, MCSE, MCDBASQL Server MVPColumnist, SQL =Server ProfessionalToronto, ON Canadahttp://www.pinnaclepublishing.com/sql">www.pinnaclepublishing.com=/sql


"John Peterson" wrote in =message news:uFC7lGbYDHA.2448=@.TK2MSFTNGP09.phx.gbl...
Tom, I'm still having trouble with =other aspects of DRI. Please see the attached DDL -- this time it's =with my R_8 relationship. I don't quite "grok" why this is =problematic. (It's not as clear-cut as a self-referencing table.)

Any additional help you can =provide would be greatly appreciated!

John Peterson

"John Peterson" wrote in =message news:%23BK4wDbYDHA.4=40@.tk2msftngp13.phx.gbl...
Thanks, Tom! Maybe I can ="mix and match" and only use triggers where necessary.
"Tom Moreau" = wrote in message news:OPg2l$aYDHA.1640=@.TK2MSFTNGP10.phx.gbl...
You cannot use DRI for cascades =on a self-referencing table. For this, you will need a trigger.
-- Tom

=---T=homas A. Moreau, BSc, PhD, MCSE, MCDBASQL Server MVPColumnist, =SQL Server ProfessionalToronto, ON Canadahttp://www.pinnaclepublishing.com/sql">www.pinnaclepublishing.com=/sql


"John Peterson" wrote =in message news:etENJ7aYDHA.2572=@.TK2MSFTNGP09.phx.gbl...(SQL Server 2000, SP3)Hello all!I am trying to use =ERwin to create a new schema. In the past, because of limitations =withSQL Server's declarative referential integrity (DRI), I typically did =all my RI throughtriggers. I thought I'd take the plunge and =try using DRI with aParent-Cascade/Child-Restrict paradigm.When =I generate the script, I get the following:CREATE TABLE =amContainer ( ContainerId =int IDENTITY(1, 1), ParentContainerId int NULL, TypeContainerId int NOT NULL, CONSTRAINT =XPKamContainer &=nbsp; PRIMARY KEY (ContainerId))goCREATE TABLE =amTypeContainer ( TypeContainerId int IDENTITY(1, 1), =Name &nb=sp; varchar(255) NOT NULL, =CONSTRAINT =XPKamTypeContainer &nb=sp; PRIMARY KEY (TypeContainerId))goALTER TABLE amContainer ADD CONSTRAINT = =R_3 = FOREIGN KEY =(TypeContainerId) &nbs=p;  =; REFERENCES =amTypeContainer = &=nbsp; ON DELETE =CASCADE &n=bsp; &nb=sp; ON UPDATE CASCADEgoALTER TABLE amContainer ADD CONSTRAINT = =R_1 = FOREIGN KEY =(ParentContainerId) &n=bsp; &nb=sp; REFERENCES =amContainer &nbs=p;  =; ON UPDATE CASCADEgoI'm getting an error on R_1 =(that last ALTER TABLE command):Server: Msg 1785, Level 16, State 1, =Line 3Introducing FOREIGN KEY constraint 'R_1' on table ='amContainer' may cause cycles ormultiple cascade paths. Specify ON DELETE NO =ACTION or ON UPDATE NO ACTION, or modifyother FOREIGN KEY constraints.Server: Msg 1750, Level 16, State 1, Line =3Could not create constraint. See previous errors.Is this not =possible with DRI? Do I need to resort to triggers to apply what I want?Thanks for any help you can provide!John =Peterson

--=_NextPart_000_0294_01C3619F.7B4E4FD0--