الانتقال إلى المحتوى

كيف اربط 1 Foreign Key بـ 2 Primary Key


repotec

Recommended Posts

السلام عليكم ورحمة الله وبركاته

كيف لي ان اربط جدول فيه foreign key بجدولين اخرين في كل واحد فيه primary key
328184032.jpg

هل استخدم triggers وعمل القيود by manual لحل هذه المشكلة

رابط هذا التعليق
شارك

وعليكم السلام ورحمة الله

رجاء ايضاح ما هى نوعية البيانات المطلوب الربط بينها ... حتى تكون الإجابة واضحة

عموما اليك هذا المثال الموضح فى الصور المرفقه ...

واليك اوامر انشاء الجداول والعلاقات بينها

/*==============================================================*/
/* Table: item                                            	*/
/*==============================================================*/
create table item  (
  item_id        	NUMBER                      	not null,
  item_name      	VARCHAR2(40),
  constraint PK_ITEM primary key (item_id)
);

/*==============================================================*/
/* Table: invoice_matser                                  	*/
/*==============================================================*/
create table invoice_matser  (
  invoice_id 		NUMBER                      	not null,
  invoice_date   	date,
  invoice_desc   	VARCHAR2(50),
  constraint PK_INVOICE_MATSER primary key (invoice_id)
);

/*==============================================================*/
/* Table: invoice_detail                                  	*/
/*==============================================================*/
create table invoice_detail  (
  invoice_id 		NUMBER                      	not null,
  item_id        	NUMBER                      	not null,
  item_quanity   	NUMBER,
  item_price 		NUMBER,
  constraint PK_INVOICE_DETAIL primary key (item_id, invoice_id)
);

alter table invoice_detail
  add constraint FK_INVOICE__REFERENCE_ITEM foreign key (item_id)
 	references item (item_id);

alter table invoice_detail
  add constraint FK_INVOICE__REFERENCE_INVOICE_ foreign key (invoice_id)
 	references invoice_matser (invoice_id);

pdm_image.jpg

erd_image.jpg

رابط هذا التعليق
شارك

أخي الحبيب ليس هذا قصدي
انظر للصورة الاتية وستفهم ماذا كنت اقصد
607781224.jpg

اي أن All_items يكون الأبن وأبواه هما in_item و out_item

لا أستطيع إدخال سجل في جدول الأبن إلا إذا كان موجود في أي من جدول الأبوين ,بمعني اخر أريد إبن له أبوين

تم تعديل بواسطة repotec
رابط هذا التعليق
شارك

يمكنك عرض شرح لطبيعة ونوعية البيانات المطلوب التعامل معها ... حتى يمكن اقتراح الحل المناسب للربط بين الجداول

السؤال عن جدولي In_item , out_item

هل يوجد تطابق فى بيانات ال items .... فى كلا الحالتين
هل يمكن ان يتم التعامل مع نفس الitem .... باعتبارة in_item و out_item

لماذا لم يتم انشاء جدول موحد للitems مع وضع عمود لتحديد نوعية الitem هل هو in or out or both
هل ترميز وتكويد ال items سوف يختلف من حيث انه in or out

اقترح عليك مبدئيا انشاء جدول واحد يحتوى البيانات الأساسية للitems

رابط هذا التعليق
شارك

ممكن تعمل اتنين foreign key constraint ... على نفس العمود يشاورا على اعمده مختلفه في جداول مختلفه ... انا جربتها و شغاله عادي
ممكن تستخدم SQL Developer في الشغل للتسهيل و تقدر تحمله من موقع اوراكل

رابط هذا التعليق
شارك

الربط عن طريق القيود لا يتناسب معي لانه عندما اقوم بادخال بيانات في الجدول All_item تريد القيود ان تكون القيمة المدخلة في كلاً من الجدولين in_item, out_item - اي موجودة في In_item و موجوده في Out_item وهذا ما لا اريده, انا اريد ان تقوم القيود ان تحقق من القيمة المدخلة علي ان تكون القيمة أما في جدول In_item أو في Out_item - لابد ان تكون موجود ولكن في احد الجدولين

لو افترضنا ان جدول in_item فيه القيم 100و120و500 وجدول out_item فيه القيم 500و220و200 عندما يقوم المستخدم بإدخال قيم في جدول All_item - بطريقة الربط العادية فالقيمة الوحيدة الصالحة للدخول في جدول all_item هي 500 لانها موجودة في الجدولين وهذا ما لا اريده - ولكني اريد ان تكون القيمة المدخلة في جدول all_item في احد الجدولين



235987496.jpg

تم تعديل بواسطة repotec
رابط هذا التعليق
شارك

create or replace trigger check_all_x_x1
 before insert on all_x  
 for each row
declare
-- cursoe to look in first table
cursor in_x1_cur is select x1 from in_x where x1 = :new.x1;
v_in_x1 number;
-- cursoe to look in second table
cursor out_x1_cur is select x1 from out_x where x1 = :new.x1;
v_out_x1 number;
begin
open in_x1_cur;
fetch in_x1_cur into v_in_x1;
close in_x1_cur;
--check if it not exist in first table
if v_in_x1 is null then -- will look in second table

open out_x1_cur;
fetch out_x1_cur into v_out_x1;
close out_x1_cur;
--check if it not exist in second table 
if v_out_x1 is null
then-- stop inserting
raise_application_error( -20001, 'check failed' );
 
else--if it exist in second table so will do nothing
null;
end if;-- the end of second if
else -- if it exist in first table will do nothing
null;
end if; -- the end of first if
end check_all_x_x1; 

رابط هذا التعليق
شارك

وهو المطلوب انا كنت اقدر اعملها لوحدي لكن كنت مستني حد يقولي الكلمتين الاخرتين اللي انت قولتهم - اني اقدر اعملهم by manual - يعني عن طريق triggers
جزاكم الله خيرا أخي الحبيب

رابط هذا التعليق
شارك

  • بعد 2 أسابيع...

لكي تعم الفائدة
هذا الكود بمثابة Primary key , Foreign key

CREATE TABLE In_item
(in_item_id NUMBER);

CREATE TABLE Out_item
(out_item_id NUMBER);

CREATE TABLE All_item
(all_item_id NUMBER);



CREATE OR REPLACE TRIGGER Item_Id_check
BEFORE INSERT OR UPDATE 
ON All_item
REFERENCING NEW AS NEW OLD AS OLD
FOR EACH ROW

DECLARE
CURSOR InItem_cur IS
                    SELECT 'anything'
                    FROM in_item
                    WHERE in_item_id =  :NEW.all_item_id;

CURSOR OutItem_cur IS
                    SELECT 'anything'
                    FROM Out_item
                    WHERE out_item_id =  :NEW.all_item_id;

Dummy CHAR(8);

BEGIN
     OPEN InItem_cur;
     FETCH InItem_cur INTO Dummy;
     IF (InItem_cur%NOTFOUND) THEN
        OPEN OutItem_cur;
        FETCH OutItem_cur INTO Dummy;
        IF (OutItem_cur%NOTFOUND) THEN
           RAISE_APPLICATION_ERROR(-20000,'constraint violated - parent not found');
        END IF;      
     END IF;
     CLOSE InItem_cur;
     CLOSE OutItem_cur;
END Item_Id_check;
/
SHOW ERR


CREATE OR REPLACE TRIGGER chk_InItem_del
BEFORE DELETE 
ON in_item
REFERENCING NEW AS NEW OLD AS OLD
FOR EACH ROW

DECLARE
 CURSOR ItemId_cur IS
                         SELECT 'anything' 
                         FROM all_item
                         WHERE all_item_id = :OLD.in_item_id;

 Dummy CHAR(8);
BEGIN
  OPEN ItemId_cur;
  FETCH ItemId_cur INTO Dummy;
  IF (ItemId_cur%FOUND) THEN  
     CLOSE ItemId_cur;
     RAISE_APPLICATION_ERROR(-20001, 'constraint violated - child record found');
  END IF;

END chk_initem_del;
/
SHOW ERR




CREATE OR REPLACE TRIGGER chk_OutItem_del
BEFORE DELETE 
ON out_item
REFERENCING NEW AS NEW OLD AS OLD
FOR EACH ROW

DECLARE
 CURSOR ItemId_cur IS
                         SELECT 'anything' 
                         FROM all_item
                         WHERE all_item_id = :OLD.out_item_id;

 Dummy CHAR(10);
BEGIN
  OPEN ItemId_cur;
  FETCH ItemId_cur INTO Dummy;
  IF (ItemId_cur%FOUND) THEN  
     CLOSE ItemId_cur;
     RAISE_APPLICATION_ERROR(-20002, 'constraint violated - child record found');
  END IF;

END chk_OutItem_del;
/
SHOW ERR

تم تعديل بواسطة repotec
رابط هذا التعليق
شارك

انضم إلى المناقشة

يمكنك المشاركة الآن والتسجيل لاحقاً. إذا كان لديك حساب, سجل دخولك الآن لتقوم بالمشاركة من خلال حسابك.

زائر
أضف رد على هذا الموضوع...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   تمت استعادة المحتوى السابق الخاص بك.   مسح المحرر

×   You cannot paste images directly. Upload or insert images from URL.

جاري التحميل
×
×
  • أضف...

برجاء الإنتباه

بإستخدامك للموقع فأنت تتعهد بالموافقة على هذه البنود: سياسة الخصوصية