इसके लिए ट्रिगर का इस्तेमाल न करें। अधिकांश शर्तें जिन्हें आपने नेस्टेड IFs (आपके ट्रिगर के) में कोडित किया है, संभवतः विदेशी कुंजी बाधाओं और चेक बाधाओं के माध्यम से की जा सकती हैं। साथ ही, आपको WOMAN_ACT के लिए 'X' को कहीं भी स्टोर करने की आवश्यकता नहीं है, क्योंकि यह एक "व्युत्पन्न मान" है यानी आप अपने डेटा की क्वेरी करते समय इसे प्राप्त या उत्पन्न कर सकते हैं। हो सकता है कि निम्नलिखित उदाहरण (आपकी मूल तालिकाओं और डेटा के आधार पर) आपको समाधान खोजने में मदद करें। कृपया कोड में टिप्पणियाँ पढ़ें।
डीडीएल कोड
create table person (
id number primary key
, registration_number varchar2(9) unique
, primary_number varchar2(9)
-- , women_act varchar2(1) <- not needed!
);
create table consolidated_numbers (
secondary_number varchar2(9) references person( registration_number )
, person_id number references person( id )
);
create table code (
valid_code varchar2(2) primary key
);
-- CHECK constraint added to allow only certain TYPE_IDs
create table history_transaction (
reason varchar2(2) references code( valid_code ) -- valid REASONSs enforced by FK constraint
, person_id number references person( id )
, type_id number check (
type_id in (
120, 140, 1420, 1440, 160, 180, 150, 1520, 1540, 1560 -- only allow these type_ids
)
)
, action_date date
);
परीक्षण डेटा
-- INSERT your initial test data
begin
insert into person (ID,registration_number,primary_number) values(132, '000000001', null);
insert into person (ID,registration_number,primary_number) values (151, '000000002', '000000001');
insert into consolidated_numbers (SECONDARY_NUMBER,person_id) values ('000000002', 132);
insert into code (valid_code) values ('A1');
insert into code (valid_code) values ('T1');
insert into code (valid_code) values ('N2');
insert into history_transaction (reason,person_id,type_id,action_date)
values ('A1', 132, 1420, DATE '2019-01-01');
commit ;
end;
/
निम्नलिखित VIEW HISTORY_TRANSACTION तालिकाओं से person_ids को पिक करेगा, उनमें से प्रत्येक में जोड़ देगा और 'X', और उन सभी व्यक्तियों को भी पिक करेगा जो CONSOLIDATED_NUMBERS से इन आईडी से "संबद्ध" हैं (या:मैप किए गए), और एक भी जोड़ें उनकी आईडी के लिए 'X'। (साइड नोट:ऐसा लगता है कि आपकी PERSON तालिका में एक पुनरावर्ती संबंध है, इसलिए कोई एक पुनरावर्ती क्वेरी लिख सकता है। हालांकि, आपके पास CONSOLIDATED_NUMBERS तालिका को मॉडलिंग करने का एक कारण होगा, इसलिए हम यहां जॉइन का उपयोग करेंगे।)
देखें
create or replace view personx
as
with PID as (
select distinct person_id
from history_transaction
)
select person_id, 'X' as woman_act -- [Q1] all person_ids from history_transaction
from PID
union
select P.id, 'X' as woman_act -- [Q2] all person_ids associated with ids from Q1
from person P
join consolidated_numbers C
on P.registration_number = C.secondary_number
and C.person_id in (
select person_id from PID
)
;
-- with your initial test data, we get:
select * from personx ;
+---------+---------+
|PERSON_ID|WOMAN_ACT|
+---------+---------+
|132 |X |
|151 |X |
+---------+---------+
अब, आइए कुछ डेटा निकालें/जोड़ें, और कुछ परीक्षण चलाएं (यह भी देखें:DBfiddle ):
-- test 1
delete from history_transaction ;
select * from personx ;
-- result: no rows selected -> OK
-- test 2
insert into history_transaction (reason,person_id,type_id,action_date)
values ('A1', 132, 1420, DATE '2019-01-01');
select * from personx ;
+---------+---------+
|PERSON_ID|WOMAN_ACT|
+---------+---------+
|132 |X |
|151 |X |
+---------+---------+
-- test 3: add more associations
begin
-- new: person 345 associated with person 132
insert into person (ID,registration_number,primary_number) values (345, '000000345', '000000001');
insert into consolidated_numbers (SECONDARY_NUMBER,person_id) values ('000000345', 132);
commit ;
end ;
/
select * from personx ;
+---------+---------+
|PERSON_ID|WOMAN_ACT|
+---------+---------+
|132 |X |
|151 |X |
|345 |X |
+---------+---------+
अधिक विवरण में जाने से पहले एक और परीक्षण:
-- test 4
-- add more associations
-- no entry in history_transactions for person(id) 1000
begin
insert into person (ID,registration_number,primary_number) values(1000, '000000777', null);
insert into person (ID,registration_number,primary_number) values (2000, '000000778', '000000777');
insert into consolidated_numbers (SECONDARY_NUMBER,person_id) values ('000000778', 1000);
commit ;
end ;
/
-- output must be the same as before -> result OK
select * from personx ;
+---------+---------+
|PERSON_ID|WOMAN_ACT|
+---------+---------+
|132 |X |
|151 |X |
|345 |X |
+---------+---------+
शामिल हों व्यक्ति तालिका के लिए दृश्य
-- test 5
-- add an entry from person 1000 into the history_transaction table
insert into history_transaction (reason,person_id,type_id,action_date)
values ('N2', 1000, 1420, sysdate);
select * from personx ;
+---------+---------+
|PERSON_ID|WOMAN_ACT|
+---------+---------+
|132 |X |
|151 |X |
|345 |X |
|1000 |X |
|2000 |X |
+---------+---------+
-- test 5: show more details
select P.id, P.registration_number, P.primary_number, PX.woman_act
from personx PX right join person P on PX.person_id = P.id ;
+----+-------------------+--------------+---------+
|ID |REGISTRATION_NUMBER|PRIMARY_NUMBER|WOMAN_ACT|
+----+-------------------+--------------+---------+
|132 |000000001 |NULL |X |
|151 |000000002 |000000001 |X |
|345 |000000345 |000000001 |X |
|1000|000000777 |NULL |X |
|2000|000000778 |000000777 |X |
+----+-------------------+--------------+---------+
बाहरी जुड़ाव उन PERSON_ID के लिए आवश्यक है जिनकी HISTORY_TRANSACTION तालिका में कोई संगत पंक्तियाँ नहीं हैं, उदाहरण के लिए
-- test 6
-- add more associations
-- no entry in history_transactions for person(id) 10000!
begin
insert into person (ID,registration_number,primary_number) values(10000, '000007777', null);
insert into person (ID,registration_number,primary_number) values (20000, '000007778', '000007777');
insert into consolidated_numbers (SECONDARY_NUMBER,person_id) values ('000007778', 10000);
commit ;
end ;
/
-- after TEST 6 data have been inserted:
select P.id, P.registration_number, P.primary_number, PX.woman_act
from personx PX right join person P on PX.person_id = P.id ;
+-----+-------------------+--------------+---------+
|ID |REGISTRATION_NUMBER|PRIMARY_NUMBER|WOMAN_ACT|
+-----+-------------------+--------------+---------+
|132 |000000001 |NULL |X |
|151 |000000002 |000000001 |X |
|345 |000000345 |000000001 |X |
|1000 |000000777 |NULL |X |
|2000 |000000778 |000000777 |X |
|20000|000007778 |000007777 |NULL |
|10000|000007777 |NULL |NULL |
+-----+-------------------+--------------+---------+
संपादित करें
यदि - जैसा कि आपकी टिप्पणी में कहा गया है - आपको WOMAN_ACT कॉलम में एक मान स्टोर करना होगा (हालांकि यह स्पष्ट रूप से "व्युत्पन्न मान" है), आप एक पैकेज लिख सकते हैं जिसमें सभी आवश्यक डीएमएल संचालन के लिए प्रक्रियाएं शामिल हैं - फिर भी ट्रिगर का उपयोग किए बिना। हालांकि, पूरी कहानी जाने बिना यह तय करना मुश्किल है कि आगे बढ़ने का यह सबसे अच्छा तरीका होगा या नहीं। निम्न उदाहरण एक छोटे पैकेज का उपयोग करता है जिसमें PERSON तालिका के WOMAN_ACT मान सेट करने के लिए प्रक्रियाएं होती हैं, और एक ट्रिगर जो INSERTs/UPDATEs (तालिका:HISTORY_TRANSACTIONS) के बाद सक्रिय होता है। DBfiddle यहां ।
व्यक्ति तालिका
create table person (
id number primary key
, registration_number varchar2(9) unique
, primary_number varchar2(9)
, woman_act varchar2(1) check ( woman_act in ( null, 'X' ) )
);
-- all other tables: same as before
पैकेज
create or replace package pxpkg
is
-- find out whether a certain id (table: PERSON) is a "parent" or a "child"
function isparent( id_ number ) return boolean ;
-- set 'X' values: id_ is a "parent"
procedure setx_parentchildren( id_ number ) ;
-- set 'X' values: id_ is a "child"
procedure setx_childsiblings( id_ number ) ;
end pxpkg ;
/
पैकेज बॉडी
create or replace package body pxpkg
is
function isparent( id_ number )
return boolean
is
secondarynumbers pls_integer := 0 ;
begin
select count(*) into secondarynumbers
from consolidated_numbers
where person_id = id_ ;
if secondarynumbers = 0 then
return false ;
else
return true ;
end if ;
end isparent ;
--
procedure setx_parentchildren ( id_ number )
is
begin
update person
set woman_act = 'X'
where id in (
select id from person where id = id_ -- parent id
union
select id from person
where primary_number = (
select registration_number from person where id = id_ -- parent id
)
) ;
end setx_parentchildren ;
--
procedure setx_childsiblings ( id_ number )
is
begin
update person
set woman_act = 'X'
where id in (
with PID as (
select id, primary_number from person
where id = id_ -- current id
and primary_number is not null -- child ids only
)
select id from PID
union
select id
from person
where registration_number in ( select primary_number from PID )
or primary_number in ( select primary_number from PID )
) ;
end setx_childsiblings ;
end pxpkg ;
/
ट्रिगर
create or replace trigger pxtrigger
after insert or update on history_transaction
for each row
begin
if pxpkg.isparent( :new.person_id ) then
pxpkg.setx_parentchildren( :new.person_id ) ;
else
pxpkg.setx_childsiblings( :new.person_id ) ;
end if ;
end pxtrigger ;
/
परीक्षण:देखें DBfiddle