ورود

View Full Version : مشکل در رابطه دو فیلد از یک فیلد در جدول دیگر



Neeloofar
شنبه 21 بهمن 1385, 13:19 عصر
سلام

جدول Table1 دارای یک کلید به نام Code هست.
جدول Table2 دو فیلد دارد که مقدارشون رو از کلید جدول table1 میگیرند.
یک دیاگرام برای رابطه این دو جدول طراحی شده.

مشکل وقتی پیدا میشه که میخوام DELETE و UPDATE رول را برای این رابطه فعال کنم و به Cascade تغییر بدم.

خطای ذیل اتفاق میافته و میگه برنامه تو یک حلقه گیر میافته.



'Table_1' table saved successfully
'Table_2' table
- Unable to create relationship 'FK_Table_2_Table_11'.
Introducing FOREIGN KEY constraint 'FK_Table_2_Table_11' on table 'Table_2' 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.


البته منطقی هست.
مشکل UPDATE و DELETE رو میشه با تریگر حل کرد. ولی میخوام بدونم دوستان راه حلی بهتر دارند یا نه؟

خوشحالم که بخش SQL Server نسبت به بخشهای دیگه فعالتر هست.

AminSobati
شنبه 21 بهمن 1385, 14:16 عصر
ارتباط بین دو جدول رو یا بصورت Declarative و یا بصورت Procedural ایجاد میکنیم. Declarative یعنی همون FK Constraint ولی Procedural یعنی به روش کد نویسی (مثلا Trigger). لذا در حالتی که جدول شما دوبار یک فیلد رو از جدولی برای Relation استفاده میکنه و اجازه نمیده Cascade کنید، تنها راه، Procedural خواهد بود. این یک روش استاندارده و ایرادی هم نداره!

Payam Moradi
شنبه 21 بهمن 1385, 22:09 عصر
گفتید "مثلا تریگر"!
یعنی راه دیگه ای هم هست.:متفکر:

AminSobati
یک شنبه 22 بهمن 1385, 12:26 عصر
و ایضا مثل Stored Procedure به هنگام ویرایش!

hadi2345
شنبه 26 اسفند 1385, 13:37 عصر
سلام جناب ثباتی عزیز ،

بعد از جستجو در مورد مشکلم ، این تاپیک رو دیدم !

آیا مثالی برای این مورد سراغ دارید ؟ من که Books Online رو جستجو کردم ولی مورد جالبی پیدا نکردم !

ممنون . . .

AminSobati
شنبه 26 اسفند 1385, 19:41 عصر
هادی جان دقیقا مثال از کدوم حالت

hadi2345
یک شنبه 27 اسفند 1385, 11:45 صبح
لذا در حالتی که جدول شما دوبار یک فیلد رو از جدولی برای Relation استفاده میکنه و اجازه نمیده Cascade کنید، تنها راه، Procedural خواهد بود. این یک روش استاندارده و ایرادی هم نداره!

اگه لطف کنید مثالی در این زمینه ذکر کنید ممنون میشم . چون الان در یک پروژه بزرگ درگیر این موضوع هستم و میخوام از تجربیات شما در حل این مشکل استفاده کنم ...

ممنون .

AminSobati
یک شنبه 27 اسفند 1385, 15:56 عصر
من این مثال رو با Power Designer درست کردم ولی تست نکردم. باید درست کار کنه:



/*================================================= =============*/
/* DBMS name: Microsoft SQL Server 2000 */
/* Created on: 3/18/2007 4:17:52 PM */
/*================================================= =============*/


if exists (select 1
from sysobjects
where id = object_id('Child')
and type = 'U')
drop table Child
go


if exists (select 1
from sysobjects
where id = object_id('Parent')
and type = 'U')
drop table Parent
go


/*================================================= =============*/
/* Table: Child */
/*================================================= =============*/
create table Child (
ParentID int null
)
go


/*================================================= =============*/
/* Table: Parent */
/*================================================= =============*/
create table Parent (
ParentID int identity,
constraint PK_PARENT primary key (ParentID)
)
go

/*================================================= =============*/
/* DBMS name: Microsoft SQL Server 2000 */
/* Created on: 3/18/2007 4:24:37 PM */
/*================================================= =============*/


if exists (select 1
from sysobjects
where id = object_id('Trigger_1')
and type = 'TR')
drop trigger Trigger_1
go


if exists (select 1
from sysobjects
where id = object_id('Trigger_1')
and type = 'TR')
drop trigger Trigger_1
go


if exists (select 1
from sysobjects
where id = object_id('Trigger_2')
and type = 'TR')
drop trigger Trigger_2
go



/* Insert trigger "Trigger_1" for table "Child" */
create trigger Trigger_1 on Child for insert as
begin
declare
@maxcard int,
@numrows int,
@numnull int,
@errno int,
@errmsg varchar(255)

select @numrows = @@rowcount
if @numrows = 0
return

/* Parent "Parent" must exist when inserting a child in "Child" */
if update(ParentID)
begin
select @numnull = (select count(*)
from inserted
where ParentID is null)
if @numnull != @numrows
if (select count(*)
from Parent t1, inserted t2
where t1.ParentID = t2.ParentID) != @numrows - @numnull
begin
select @errno = 50002,
@errmsg = 'Parent does not exist in "Parent". Cannot create child in "Child".'
goto error
end
end

return

/* Errors handling */
error:
raiserror @errno @errmsg
rollback transaction
end
go


/* Delete trigger "Trigger_1" for table "Parent" */
create trigger Trigger_1 on Parent for delete as
begin
declare
@numrows int,
@errno int,
@errmsg varchar(255)

select @numrows = @@rowcount
if @numrows = 0
return

/* Delete all children in "Child" */
delete Child
from Child t2, deleted t1
where t2.ParentID = t1.ParentID


return

/* Errors handling */
error:
raiserror @errno @errmsg
rollback transaction
end
go


/* Update trigger "Trigger_2" for table "Parent" */
create trigger Trigger_2 on Parent for update as
begin
declare
@maxcard int,
@numrows int,
@numnull int,
@errno int,
@errmsg varchar(255)

select @numrows = @@rowcount
if @numrows = 0
return

/* Modify parent code of "Parent" for all children in "Child" */
if update(ParentID)
begin
update Child
set ParentID = i1.ParentID
from Child t2, inserted i1, deleted d1
where t2.ParentID = d1.ParentID
and (i1.ParentID != d1.ParentID)
end


return

/* Errors handling */
error:
raiserror @errno @errmsg
rollback transaction
end
go