check constraint on column [message #600466] |
Thu, 07 November 2013 00:48 |
|
sanjlaxmi
Messages: 24 Registered: October 2013
|
Junior Member |
|
|
In applicant table have start_date column.now i can insert any date in that table.
i want to allow to create record after 6 month of start date which is already in table for all rows.
i.e to allow duplicate record but date should be greater than 6 month alredy added rows.
i had tried to add check constraint on column but its not working..
Tell me how to add check constraint for date by using simple example
and how its possible to create duplicate record which is alredy in table but with start date greater than 6 months.
thanx in advance...
|
|
|
Re: check constraint on column [message #600472 is a reply to message #600466] |
Thu, 07 November 2013 02:44 |
|
Littlefoot
Messages: 21807 Registered: June 2005 Location: Croatia, Europe
|
Senior Member Account Moderator |
|
|
I think that check constraint itself can't do that - therefore, you need to use a database trigger. Here's an example: I'm creating a table first, then a trigger which makes sure that you can't enter another START_DATE for the same APPL_ID that is within the 6 months range.
SQL> create table test
2 ( appl_id number,
3 start_date date
4 );
Table created.
SQL> create or replace trigger trg_biu_test
2 before insert or update
3 on test
4 for each row
5 declare
6 l_max_date date;
7 begin
8 select max (t.start_date)
9 into l_max_date
10 from test t
11 where t.appl_id = :new.appl_id;
12
13 if months_between(:new.start_date, l_max_date) < 6 then
14 raise_application_error (-20001, '6 months between two dates are required');
15 end if;
16 end;
17 /
Trigger created.
SQL>
Let's test it: the first record is inserted, but the second one failed because it is only 3 months later:
SQL> insert into test (appl_id, start_date) values (1, date '2013-01-15');
1 row created.
SQL> insert into test (appl_id, start_date) values (1, date '2013-04-15');
insert into test (appl_id, start_date) values (1, date '2013-04-15')
*
ERROR at line 1:
ORA-20001: 6 months between two dates are required
ORA-06512: at "SCOTT.TRG_BIU_TEST", line 10
ORA-04088: error during execution of trigger 'SCOTT.TRG_BIU_TEST'
SQL>
How about August?SQL> insert into test (appl_id, start_date) values (1, date '2013-08-15');
1 row created.
Seems to be OK.
Test it a little bit more and see if it suits your needs.
|
|
|
Re: check constraint on column [message #600477 is a reply to message #600472] |
Thu, 07 November 2013 02:55 |
cookiemonster
Messages: 13920 Registered: September 2008 Location: Rainy Manchester
|
Senior Member |
|
|
That trigger won't work for update or insert/select:
SQL> update test set appl_id = 2;
update test set appl_id = 2
ORA-04091: table LIVE.TEST is mutating, trigger/function may not see it
ORA-06512: at "LIVE.TRG_BIU_TEST", line 4
ORA-04088: error during execution of trigger 'LIVE.TRG_BIU_TEST'
SQL> insert into test select rownum, sysdate from dual connect by level < 3;
insert into test select rownum, sysdate from dual connect by level < 3
ORA-04091: table LIVE.TEST is mutating, trigger/function may not see it
ORA-06512: at "LIVE.TRG_BIU_TEST", line 4
ORA-04088: error during execution of trigger 'LIVE.TRG_BIU_TEST'
SQL>
To do something like this I think you need to involve a materialized view.
|
|
|
|
|
Re: check constraint on column [message #600480 is a reply to message #600478] |
Thu, 07 November 2013 03:16 |
cookiemonster
Messages: 13920 Registered: September 2008 Location: Rainy Manchester
|
Senior Member |
|
|
Littlefoot wrote on Thu, 07 November 2013 09:00
Materialized view, you say? Could you describe what you mean? I can't imagine what to do with it ...
Not really, it's a vague recollection of something I saw on asktom and I might be imagining it. Solomon may have an idea.
|
|
|
Re: check constraint on column [message #600481 is a reply to message #600479] |
Thu, 07 November 2013 03:18 |
cookiemonster
Messages: 13920 Registered: September 2008 Location: Rainy Manchester
|
Senior Member |
|
|
mughals_king wrote on Thu, 07 November 2013 09:01 Example
create table test
(dt_start DATE,
dt_end DATE,
constraint chk_strt check (dt_end >= dt_start));
Insert into test VALUES (sysdate, sysdate + 6);
You've misunderstood the question, the new row needs to be checked against existing ones.
|
|
|
Re: check constraint on column [message #600482 is a reply to message #600480] |
Thu, 07 November 2013 03:24 |
ThomasG
Messages: 3211 Registered: April 2005 Location: Heilbronn, Germany
|
Senior Member |
|
|
cookiemonster wrote on Thu, 07 November 2013 10:16Not really, it's a vague recollection of something I saw on asktom and I might be imagining it.
I remembered that one, too. Was it the Best way to enforce cross-row constraints? discussion.
Too bad they it didn't come up with a "best" way, only with different slightly-different-drawbacks ways, the "Best" way being to do the insert via an procedure or other API, not with direct sql.
|
|
|
|
|
Re: check constraint on column [message #600485 is a reply to message #600484] |
Thu, 07 November 2013 03:35 |
cookiemonster
Messages: 13920 Registered: September 2008 Location: Rainy Manchester
|
Senior Member |
|
|
in forms - when-validate-item or when-validate record.
But if two users are adding data at the same time that will not prevent both of them adding a new record for the same id, leading to invalid duplicates. If you want to be sure you need to use the materialized view method from the asktom link above.
|
|
|
|
Re: check constraint on column [message #600489 is a reply to message #600482] |
Thu, 07 November 2013 04:54 |
Solomon Yakobson
Messages: 3273 Registered: January 2010 Location: Connecticut, USA
|
Senior Member |
|
|
ThomasG wrote on Thu, 07 November 2013 04:24Too bad they it didn't come up with a "best" way, only with different slightly-different-drawbacks ways, the "Best" way being to do the insert via an procedure or other API, not with direct sql.
And how would procedure resolve multi-session inserts? As Tom said, you need some serialization one way or another. Neither insert nor procedure provide that. You would have to use some sort of mechanism to communicate between sessions. Locking, queueing, MV, global context, ...
SY.
[EDITED by LF: fixed [quote] tags]
[Updated on: Fri, 08 November 2013 03:10] by Moderator Report message to a moderator
|
|
|
Re: check constraint on column [message #600556 is a reply to message #600472] |
Thu, 07 November 2013 22:47 |
|
sanjlaxmi
Messages: 24 Registered: October 2013
|
Junior Member |
|
|
this is code i have written...
declare
max_date date;
begin
--for each row
select max(:start_dt)
into max_date
from applicant
where :apl_nmbr = :apl_nmbr;
if months_between(:start_dt,max_date) < 6 then
message('6 months between two dates are required');
end if;
end;
i made some changes in code which i got from here..i am using when validate item trigger and wrote this code
i am adding duplicate record with F4 function key
but its still saving the record if i enter new date 1-feb-2012 with respect to first record, date 1-jan-2012.
so it should not save the record ...it should only save if difference between them is greater than 6 month.
and is it posssible to use for each row in code?its giving error if i try to use in trigger of oracle form 6i
i have to check for every record inserted in table before date update for that purpose i have to loop it
but cant understanding how to use it?
pls try to help out..
Thanx
[Updated on: Thu, 07 November 2013 23:13] Report message to a moderator
|
|
|
|
Re: check constraint on column [message #600564 is a reply to message #600561] |
Fri, 08 November 2013 02:39 |
cookiemonster
Messages: 13920 Registered: September 2008 Location: Rainy Manchester
|
Senior Member |
|
|
This isn't going to work if multiple users enter data for the same apl_nmbr at the same time anyway, as I already pointed out.
You have to use the materialized view method in the asktom link.
I will point out that your where clause is wrong:
where :apl_nmbr = :apl_nmbr
should have been
where apl_nmbr = :apl_nmbr
but it's a moot point as this is the wrong approach.
|
|
|
Re: check constraint on column [message #600566 is a reply to message #600466] |
Fri, 08 November 2013 03:02 |
ejdrba
Messages: 27 Registered: May 2005 Location: Kolkata
|
Junior Member |
|
|
Hi,
Try out this trigger -
CREATE OR REPLACE TRIGGER trg_biu_test
BEFORE INSERT OR UPDATE OF start_date
ON TESTT
FOR EACH ROW
DECLARE
l_max_date DATE;
BEGIN
SELECT MAX (t.start_date)
INTO l_max_date
FROM TESTT t
WHERE t.appl_id = :NEW.appl_id;
IF MONTHS_BETWEEN (:NEW.start_date, l_max_date) < 6
THEN
raise_application_error (-20001,
'6 months between two dates are required'
);
END IF;
END;
Regards,
Debraj
[EDITED by LF: fixed [code] tags]
[Updated on: Fri, 08 November 2013 03:11] by Moderator Report message to a moderator
|
|
|
|
|
|