How is unique constraint applied from more than one table in oracle? - sql

I have 3 tables is shown this tables:
table A
A(
code1
.
.
.
)
table B
B(
code2
.
.
.
)
table C
C(
code3
.
.
.
)
I want to be unique between code1,code2,code3 of this tables.
How do i recieve to my goal in oracle?
Does any syntax of oracle exist about this problem?

Based on materialized view.
P.s.
The code is not validated.
I currently have access only to oracle XE 11gR2, so I'm not able to use the materialized view log feature.
create table A (code int primary key);
create table B (code int primary key);
create table C (code int primary key);
create materialized view log on a with primary key;
create materialized view log on b with primary key;
create materialized view log on c with primary key;
create materialized view ABC_MV
refresh fast
as
select code from A
union all select code from B
union all select code from C
;
alter table ABC_MV add unique (code);

You can do that with trigger.
CREATE OR REPLACE TRIGGER table1_check
BEFORE INSERT OR UPDATE ON table1
FOR EACH ROW
BEGIN
IF EXISTS (
SELECT attribute FROM table2
WHERE attribute = :NEW.attribute
) THEN
RAISE_APPLICATION_ERROR(-20001,
'Already exist in table2');
END IF;
END;
/
You can modify it to check in more tables as well.

Using a 4th table
create table ABC (tab char(1) not null ,code int primary key, unique (tab,code));
create table A (tab char(1) as ('A') virtual not null,code int primary key,foreign key (tab,code) references ABC(tab,code));
create table B (tab char(1) as ('B') virtual not null,code int primary key,foreign key (tab,code) references ABC(tab,code));
create table C (tab char(1) as ('C') virtual not null,code int primary key,foreign key (tab,code) references ABC(tab,code));
insert into ABC (tab,code) values ('A',1);
insert into A (code) values (1);
insert into A (code) values (1);
[Code: 1, SQL State: 23000] ORA-00001: unique constraint (SYS.SYS_C0012834) violated
insert into B (code) values (1);
[Code: 2291, SQL State: 23000] ORA-02291: integrity constraint
(SYS.SYS_C0012839) violated - parent key not found

Related

Oracle if value to be inserted in foreign key is -1, insert null instead

I have a xml script I'm reading from to populate my database with data. One of the nodes in the xml file don't have a idDirector field (the nodes are movies) and so the xml reads a -1 as idDirector and then my stored procedure tries to insert -1 into the fk field and this makes my database returna constraint error : director -1 doesn't exist in Director table. How can I make it so it inserts null instead and make my fk field nullable?
CREATE TABLE Film (
PRIMARY KEY (idFilm),
FOREIGN KEY (idDirector) REFERENCES Director
);
Thank you
Looks like CASE to me, e.g.
insert into film (id_film, id_director)
select id_film,
case when id_director = -1 then null
else id_director
end
from ...
Will it work? Yes:
SQL> create table director (id number primary key);
Table created.
SQL> create table film (id number primary key, id_director number references director);
Table created.
SQL> insert into director values (100);
1 row created.
Inserting -1 fails:
SQL> insert into film (id, id_director) values (1, -1);
insert into film (id, id_director) values (1, -1)
*
ERROR at line 1:
ORA-02291: integrity constraint (SCOTT.SYS_C0065885) violated - parent key not
found
Inserting NULL works:
SQL> insert into film (id, id_director) values (1, null);
1 row created.
SQL>

Sql (Oracle)-- cannot insert value(could be the constraint factor)

As you can see in the code. three table have its own primary key. "protectmedalno" and "mastermedalno" are the foreign key of the player table.
protectmedalno could not be null. masterdealno could be null. I drop table protector first, then drop master , the last drop player.
There is weak relationship between table player and table master.
There is no problem with inserting the value of protector and master.
But inserting the value into table player, it will occur:
*Cause: A foreign key value has no matching primary key value.
*Action: Delete the foreign key or add a matching primary key.
I think that it is a problem with constraint.
insert into player values('01','Joe','101','');
insert into player values('02','Elsa','102','201');
insert into protector values('101','Dragon');
insert into protector values('102','Lion');
insert into master values('201','Fairy')
commits;
It could display the protector table and the master table.
But it could not show the player table.
drop table protector;
drop table master;
drop table player;
CREATE TABLE player (
playno NUMBER(2) NOT NULL,
playname VARCHAR2(30) NOT NULL,
protectmedalno CHAR(10) NOT NULL,
mastermedalno CHAR(10)
);
ALTER TABLE player ADD CONSTRAINT play_pk PRIMARY KEY ( playno );
CREATE TABLE protector (
protectmedalno CHAR(3) NOT NULL,
protectname VARCHAR2(30) NOT NULL
);
ALTER TABLE protector ADD CONSTRAINT protector_pk PRIMARY KEY ( protectmedalno );
CREATE TABLE master (
mastermedalno CHAR(3) NOT NULL,
mastername VARCHAR2(30) NOT NULL
);
ALTER TABLE master ADD CONSTRAINT master_pk PRIMARY KEY ( mastermedalno );
ALTER TABLE player
ADD CONSTRAINT player_protector_fk FOREIGN KEY ( protectmedalno )
REFERENCES protector ( protectmedalno );
ALTER TABLE player
ADD CONSTRAINT player_master_fk FOREIGN KEY ( mastermedalno )
REFERENCES master ( mastermedalno );
Since protector and master are the primary tables, you should populate the records there first. Then, insert into player and refer to those records:
insert into protector values('101','Dragon');
insert into protector values('102','Lion');
insert into master values('201','Fairy');
insert into player values('01','Joe','101','201'); -- refer to master
insert into player values('02','Elsa','102','201'); -- refer to master
Note that I edited the inserts into the player table such that both records refer to a record in the master table which actually exists.
You first have to insert protector and master, afterwards insert player since player refers to master and protector and values have to be inside there.
Do otherwise round on delete...
insert into protector values('101','Dragon');
insert into protector values('102','Lion');
insert into master values('201','Fairy');
insert into player values('01','Joe','101','');
insert into player values('02','Elsa','102','201');
If you delete first delete from player, then from protector and master.
To insert data in the player table, you need a record in the protector table. This is because of the foreign key restriction.
When inserting data in a table that has a foreign key(Which in this case of protector vs player, cannot be null), you have to create the foreign record first.
1. insert into protector values('101','Dragon');
2. insert into player values('01','Joe','101','');
3. insert into protector values('102','Lion');
4. insert into master values('201','Fairy');
5. insert into player values('02','Elsa','102','201');
commits;
I hope this helps, happy debugging :)
You are inserting in the wrong order: you must insert the master and protector first so that when you insert the player it can reference them:
insert into protector values('101','Dragon');
insert into protector values('102','Lion');
insert into master values('201','Fairy');
insert into player values('01','Joe','101',NULL);
insert into player values('02','Elsa','102','201');
Edit: '' is not NULL it's an empty String. To insert null use the explicit NULL jeyword.
Always include the columns when doing an insert. You should also use single quotes for only string and date constants.
insert into player(playno, playname, protectmedalno, mastermedalno)
values(1, 'Joe', '101', '');
I don't think the problem is specifically on player, but you should do this for all your inserts and you'll find the problem.
Populating the "parent" tables first (as our colleagues have suggested) is a step towards solving the problem. In order to get the foreign key constraint to work properly, I suggest modifying the DDL code, too.
With your tables in place (using Oracle 12c), we can do the following:
begin
insert into master ( mastermedalno, mastername ) values ('201','Fairy') ;
insert into protector ( protectmedalno, protectname )
values( '101', 'Dragon');
insert into protector ( protectmedalno, protectname )
values( '102', 'Lion');
end ;
/
SQL> select * from master;
MAS MASTERNAME
--- ------------------------------
201 Fairy
SQL> select * from protector ;
PRO PROTECTNAME
--- ------------------------------
101 Dragon
102 Lion
So far so good. When INSERTing into PLAYER, we get:
insert into player ( playno, playname, protectmedalno, mastermedalno )
values('02', 'Elsa', '102', '201');
-- ORA-02291: integrity constraint (...PLAYER_MASTER_FK) violated - parent key not found
Suggestion: use the same datatype for the foreign key and the referenced key. Just drop the PLAYER table (including its constraints), and create it afresh:
drop table player cascade constraints ;
CREATE TABLE player (
playno NUMBER(2) NOT NULL,
playname VARCHAR2(30) NOT NULL,
protectmedalno CHAR(3) NOT NULL, -- changed (was: CHAR(10))
mastermedalno CHAR(3) -- changed (was: CHAR(10))
);
ALTER TABLE player
ADD CONSTRAINT player_protector_fk FOREIGN KEY ( protectmedalno )
REFERENCES protector ( protectmedalno );
ALTER TABLE player
ADD CONSTRAINT player_master_fk FOREIGN KEY ( mastermedalno )
REFERENCES master ( mastermedalno );
Now execute the INSERTs.
begin
insert into player values('01','Joe','101',''); -- original INSERT
insert into player values('02','Elsa','102','201'); -- original INSERT
commit;
end;
/
-- PL/SQL procedure successfully completed.
The tables contain the following data now:
SQL> select * from player ;
PLAYNO PLAYNAME PROTECTMEDALNO MASTERMEDALNO
1 Joe 101 NULL
2 Elsa 102 201
SQL> select * from master ;
MASTERMEDALNO MASTERNAME
201 Fairy
SQL> select * from protector;
PROTECTMEDALNO PROTECTNAME
101 Dragon
102 Lion
Are both foreign key constraints working now? Yes.
SQL> insert into player values('03','Fifi','101','202');
Error starting at line : 1 in command -
insert into player values('03','Fifi','101','202')
Error report -
ORA-02291: integrity constraint (...PLAYER_MASTER_FK) violated - parent key not found
SQL> insert into player values('03','Fifi','103','201');
Error starting at line : 1 in command -
insert into player values('03','Fifi','103','201')
Error report -
ORA-02291: integrity constraint (...PLAYER_PROTECTOR_FK) violated - parent key not found

How to create a table with ONE existing row from another table?

I'm frankly new to sql and this is a project I'm doing.
I would like to know if there's a way to connect one column in one table to another table when creating tables. I know of the join method to show results of, but I want to minimized my code as possible.
CREATE TABLE players (
id INT PRIMARY KEY, -->code I want connect with table match_record
player_name CHARACTER
);
CREATE TABLE match_records (
(id INT PRIMARY KEY /*FROM players*/), --> the code I want it to be here
winner INT,
loser INT
);
CREATE TABLE players (
id INT not null PRIMARY KEY, -->code I want connect with table match_record
player_name CHARACTER
);
CREATE TABLE match_records (
id INT not null PRIMARY KEY references players(id), --> the code I want it to be here
winner INT,
loser INT
);
this way you restrict that match_records.id is only from players.id:
t=# insert into match_records select 1,1,0;
ERROR: insert or update on table "match_records" violates foreign key constraint "match_records_id_fkey"
DETAIL: Key (id)=(1) is not present in table "players".
So I add players:
t=# insert into players(id) values(1),(2);
INSERT 0 2
And now it allows insert:
t=# insert into match_records select 1,1,0;
INSERT 0 1
update
https://www.postgresql.org/docs/current/static/app-psql.html#APP-PSQL-PROMPTING
%#
If the session user is a database superuser, then a #, otherwise a >.
(The expansion of this value might change during a database session as
the result of the command SET SESSION AUTHORIZATION.)
in this way:
CREATE TABLE new_table as SELECT id,... from old_table where id = 1;

CHECK constraint in SQL Server not allowing to exceed value from foreign key

I have the following two tables:
CREATE TABLE test1
(
ID int IDENTITY UNIQUE,
length int not null
)
CREATE TABLE test2
(
ID int IDENTITY UNIQUE,
test1number int references test1(ID),
distance int not null
)
Example: lets insert into test1 values 1 and 100 (ID=1 and length=100). Now lets insert into test2 values 1 as ID and test1number=1 as reference from test1. I want to create a constraint which will not allow to write distance bigger than 100 (length from test1).
Any other way than procedure?
If this is for individual rows, and we don't need to assert some property about all rows with the same test1number values then one way to do it is this:
CREATE TABLE test1
(
ID int IDENTITY UNIQUE,
length int not null,
constraint UQ_test1_Length_XRef UNIQUE (ID,Length)
)
go
CREATE TABLE _test2
(
ID int IDENTITY UNIQUE,
test1number int references test1(ID),
_test1length int not null,
distance int not null,
constraint FK_test2_test1_length_xref foreign key (test1number,_test1length)
references test1 (ID,length) on update cascade,
constraint CK_length_distance CHECK (distance <= _test1length)
)
go
create view test2
as
select ID,test1number,distance from _test2
go
create trigger T_I_t2 on test2
instead of insert
as
insert into _test2(test1number,_test1length,distance)
select test1number,length,distance
from inserted i inner join test1 t on i.test1number = t.id
go
We only need the view and trigger if you're trying to hide the existence of this extra column in the _test2 table from your users.

Getting the primary key back from a SQL insert with SQLite

I have a SQL table set that looks like this
create table foo (
id int primary key asc,
data datatype );
create table bar (
id int primary key asc,
fk_foo int,
foreign key(foo_int) references foo(id));
Now, I want to insert a record set.
insert into table foo (data) values (stuff);
But wait - to get Bar all patched up hunkydory I need the PK from Foo. I know this is a solved problem.
What's the solution?
try this
SELECT last_insert_rowid()