I come the to problem with creating database table over JPA. I have some atributes for creating database table together with two fields for Date. I need to make sure, that input for DateEnd must be bigger than input for DateStart
#Column(name="START")
private LocalDate dateStart
#Column(name="END")
private LocalDate dateEnd
Thanks for any advice
It's not possible on entity level, you should define your custom costraint with its javax.validation.ConstraintValidator implementation. See here for documentation.
As you tagged it as an "Oracle" question, and if you want to do that in the database, a natural choice would be the CHECK constraint.
Here's an example (note that the date literal's format is 'YYYY-MM-DD'):
SQL> create table test (id number, date_start date, date_end date);
Table created.
SQL> alter table test add constraint ch_test_date check (date_start <= date_end);
Table altered.
SQL> insert into test values (1, date '2018-03-19', date '2018-05-10');
1 row created.
SQL> update test set date_end = date '2010-01-02' where id = 1;
update test set date_end = date '2010-01-02' where id = 1
*
ERROR at line 1:
ORA-02290: check constraint (SCOTT.CH_TEST_DATE) violated
SQL> insert into test values (1, date '2018-03-19', date '2018-01-02');
insert into test values (1, date '2018-03-19', date '2018-01-02')
*
ERROR at line 1:
ORA-02290: check constraint (SCOTT.CH_TEST_DATE) violated
SQL>
Related
Im trying to build a sample database for a project about a real estate agency,on the table about the realties i have a column Realtie_id and i want it to start with 11%%% what type should it be (int or varchar ) and how do I make the constraint ?
create table Realties (
rid int not null,
address varchar(50),
m2 real not null,
r_type varchar(20),
primary key (rid),
constraint c_rid check(rid in (.....
);
It depends on what you'll be storing in there.
if it is a string, use VARCHAR2
if it is a number, use NUMBER (or INT)
Constraint in any case might be
SQL> create table realties
2 (rid int constraint ch_rid check (substr(to_char(rid), 1, 2) = '11'));
Table created.
SQL> insert into realties (rid) values ('abc');
insert into realties (rid) values ('abc')
*
ERROR at line 1:
ORA-01722: invalid number
SQL> insert into realties (rid) values ('245');
insert into realties (rid) values ('245')
*
ERROR at line 1:
ORA-02290: check constraint (SCOTT.CH_RID) violated
SQL> insert into realties (rid) values ('1245');
insert into realties (rid) values ('1245')
*
ERROR at line 1:
ORA-02290: check constraint (SCOTT.CH_RID) violated
SQL> insert into realties (rid) values ('11245');
1 row created.
SQL>
If your value is a number then make the column a numeric data type. The exception to this is when your value is a number string that can start with zeroes, like a phone number, when it should be a string data type; otherwise if you use a number data type then the, semantically important, leading zeroes will be stripped off. Since you want the number to start with 11 then this caveat does not apply.
As for the CHECK constraint, you can use LIKE '11%' and Oracle will implicitly convert it to a string to perform the check.
create table Realties (
rid int
not null
CONSTRAINT realties__rid__pk PRIMARY KEY
CONSTRAINT realties__rid__chk CHECK ( rid LIKE '11%' ),
address varchar(50),
m2 real
not null,
r_type varchar(20)
);
I am trying to come up with a way to make sure that when a table is updated, that a certain condition is met. Can this be done in a trigger? I have made the following two tables, storeTable and employeeTable.
I need to make sure that when storeManager is updated in the storeTable, that the employee has a storeID that matches the store in which I am trying to update the storeManager. (employee cannot be manager of a store he does not work at)
In addition, I need to make sure that the employee exists in the employeeTable. I was thinking some sort of CASE statement would be best, but dont know how this could be enforced by a trigger.
I was thinking about morphing the "Foreign Key Trigger for Child Table" trigger example from https://docs.oracle.com/cd/B12037_01/appdev.101/b10795/adfns_tr.htm#1007172 but I could not figure out how to change this to fit my specific need. Any help is much appreciated.
For context, the current keys are:
storeTable:
storeID PRIMARY KEY
employeeTable:
empID PRIMARY KEY
storeID FOREIGN KEY REFERS TO storeTable.storeID
To me, it seems that constraints can do the job. You don't need triggers.
Here's how. First, create tables without any constraints. Then add them, both primary and foreign key ones which will be deferrable (otherwise you wouldn't be able to insert any rows as parent keys don't exist yet).
SQL> create table employee
2 (empid number,
3 fname varchar2(10),
4 storeid number
5 );
Table created.
SQL> create table store
2 (storeid number,
3 storename varchar2(20),
4 storemanager number
5 );
Table created.
SQL>
SQL> alter table employee add constraint pk_employee primary key (empid, storeid);
Table altered.
SQL> alter table store add constraint pk_store primary key (storeid);
Table altered.
SQL>
SQL> alter table store add constraint fk_store_emp foreign key (storemanager, storeid)
2 references employee (empid, storeid)
3 deferrable initially deferred;
Table altered.
SQL> alter table employee add constraint fk_emp_store foreign key (storeid)
2 references store (storeid)
3 deferrable initially deferred;
Table altered.
SQL>
Now let's add some data: initial insert into employee will be OK until I commit - then it'll fail because its store doesn't exist yet:
SQL> insert into employee values (1, 'John' , 1);
1 row created.
SQL> commit;
commit
*
ERROR at line 1:
ORA-02091: transaction rolled back
ORA-02291: integrity constraint (SCOTT.FK_EMP_STORE) violated - parent key not
found
SQL>
But, if I don't commit and pay attention to what I'm entering (i.e. that referential integrity is maintained), it'll be OK:
SQL> insert into employee values (1, 'John' , 1);
1 row created.
SQL> insert into employee values (2, 'Matt' , 2);
1 row created.
SQL> insert into store values (1, 'Santa Clara', 1);
1 row created.
SQL> insert into store values (2, 'San Francisco', 2); --> note 2 as STOREID
1 row created.
SQL> commit;
Commit complete.
SQL> select * From employee;
EMPID FNAME STOREID
---------- ---------- ----------
1 John 1
2 Matt 2
SQL> select * From store;
STOREID STORENAME STOREMANAGER
---------- -------------------- ------------
1 Santa Clara 1
2 San Francisco 2
SQL>
See? So far so good.
Now I'll try to modify STORE table and set its manager to John who works in storeid = 1 which means that it should fail:
SQL> update store set storemanager = 1
2 where storeid = 2;
1 row updated.
SQL> commit;
commit
*
ERROR at line 1:
ORA-02091: transaction rolled back
ORA-02291: integrity constraint (SCOTT.FK_STORE_EMP) violated - parent key not
found
SQL>
As expected.
Let's now add emplyoee ID = 6, Jimmy, who works in storeid = 2 and set him to be manager in San Francisco (storeid = 2):
SQL> insert into employee values (6, 'Jimmy', 2);
1 row created.
SQL> update store set storemanager = 6
2 where storeid = 2;
1 row updated.
SQL> commit;
Commit complete.
SQL>
Yey! It works!
As you can see, no triggers needed.
Note that - if you want to drop any of those tables - you'll fail as they are referenced by each other:
SQL> drop table store;
drop table store
*
ERROR at line 1:
ORA-02449: unique/primary keys in table referenced by foreign keys
SQL> drop table employee;
drop table employee
*
ERROR at line 1:
ORA-02449: unique/primary keys in table referenced by foreign keys
SQL>
It means that you'd first have to drop foreign key constraints, then drop tables:
SQL> alter table employee drop constraint fk_emp_store;
Table altered.
SQL> alter table store drop constraint fk_store_emp;
Table altered.
SQL> drop table store;
Table dropped.
SQL> drop table employee;
Table dropped.
SQL>
That's all, I guess.
I'm having hard time to add a new colomn of date of birth with the check rule age between 18 and 65.
I'm using sqplus with Oracle
Alway getting the error message ORA00920
Need your help please
ALTER TABLE Vendeur ADD (dateNaissance DATE,
dateDebutProjet DATE NOT NULL,
DateFinProjet DATE NOT NULL,
CONSTRAINT chk_date_Birth CHECK ((TRUNC(CURRENT_DATE)-dateNaissance)
BETWEEN 18 AND 65),
CONSTRAINT chk_date_Projet CHECK (DateFinProjet > dateDebutProjet));
if it can help, the solution without triggers (since we didn't learn hem at that time):
ALTER TABLE Vendeur ADD (dateNaissance DATE,
debutProjet DATE DEFAULT '01/01/1000' NOT NULL,
finProjet DATE DEFAULT '02/01/1000' NOT NULL,
dateDuJour Date DEFAULT CURRENT_DATE,
CONSTRAINT chk_date_Projet CHECK (finProjet > debutProjet),
CONSTRAINT chk_date_Birth CHECK ((dateDuJour - dateNaissance)\365 BETWEEN 18 AND 65)
);
Check constraints cannot call non-deterministic functions like CURRENT_DATE. Check constraints are supposed to always be true, weird things might happen if check constraints aged out.
The below sample code shows one of the errors you might get trying to use CURRENT_DATE in a check constraint:
SQL> create table test1(a date);
Table created.
SQL> alter table test1 add constraint test1_ck1 check(a > date '2000-01-01');
Table altered.
SQL> alter table test1 add constraint test1_ck2 check(a > current_date);
alter table test1 add constraint test1_ck2 check(a > current_date)
*
ERROR at line 1:
ORA-02436: date or system variable wrongly specified in CHECK constraint
Create a trigger to workaround this problem:
create or replace trigger test1_date_gt_today
before update or insert of a on test1
for each row
begin
if :new.a is null or :new.a < current_date then
raise_application_error(-20000, 'The date cannot be earlier than today.');
end if;
end;
/
Below is an example of one INSERT working, and one failing to meet the condition in the trigger:
SQL> insert into test1 values(sysdate + 1);
1 row created.
SQL> insert into test1 values(sysdate - 1);
insert into test1 values(sysdate - 1)
*
ERROR at line 1:
ORA-20000: The date cannot be earlier than today.
ORA-06512: at "JHELLER.TEST1_DATE_GT_TODAY", line 3
ORA-04088: error during execution of trigger 'JHELLER.TEST1_DATE_GT_TODAY'
I'm trying to set the default date of the EmpDate column as the current system date. How do I do it in oracle sql? Besides, how do I add multiple column in one command(instead of using two separate ALTER like the code shown below)?
The question is "Add two columns to the EMPLOYEES table. One column, named EmpDate, contains the date of employment for each employee, and its default value should be the system date. The second column, named EndDate, contains employees’ date of termination."
ALTER TABLE EMPLOYEES
Add EmpDate Date;
ALTER TABLE EMPLOYEES
Add EndDate Date;
ALTER TABLE EMPLOYEES
ADD CONSTRAINT empdate
DEFAULT GETDATE() FOR EmpDate;
alter table Employees add Empdate date default sysdate;
alter table Employees add Enddateq date ;
How to increment the value of the unique constraint column value in ORACLE, in the select statement.
For example, in a table 'BILLING_TABLE' - column BLNG_Sk is the unique key (Autoincremented).
So while inserting a new record into the BILLING_TABLE, for the column BLNG_SK we need to give the value (Which is the increment by 1 from the present max value.)
For example, if BLNG_SK max value is 12321.
new record should be 12322.
how to achieve this in Oracle?
Oracle has a SEQUENCE object which provides the functionality you require.
You create one using the CREATE SEQUENCE SQL statement.
The Oracle documentation provides all the required information and the documentation is available via Oracle's Web site.
Assuming you are on Oracle 12.1 or later, define it as an identity column and do not pass any value when inserting:
create table testtable
( test_id number generated always as identity
constraint testtable_pk primary key
, othercol varchar2(10) );
insert into testtable (othercol) values ('Demo');
select * from testtable;
TEST_ID OTHERCOL
---------- ----------
1 Demo
insert into testtable (othercol) values ('Demo #2');
select * from testtable;
TEST_ID OTHERCOL
---------- ----------
1 Demo
2 Demo #2
Try creating a sequence and a trigger. This is the case when you provide the value manually.
CREATE SEQUENCE dept_seq START WITH 12322;
Trigger definition:
CREATE OR REPLACE TRIGGER dept_bir
BEFORE INSERT ON BILLING_TABLE
FOR EACH ROW
BEGIN
SELECT dept_seq.NEXTVAL
INTO :new.id
FROM dual;
END;
/