Oracle adding records from multiple tables - sql

My objective is to build a master Serial No table from many different tables and each Serial No must be unique.
CREATE TABLE "TBL_SERIAL_NUMBER_MASTER"
( "INTERNAL_RECORD_ID" VARCHAR2(60) NOT NULL ENABLE,
"ASSET_ID" VARCHAR2(60),
"SERIAL_NUMBER" VARCHAR2(1000) NOT NULL ENABLE,
"VALID" VARCHAR2(60) DEFAULT 'Valid',
"HOST_NAME" VARCHAR2(255),
CHECK ( valid IN ('Invalid', 'Valid')) ENABLE,
CHECK ( valid IN ('Invalid', 'Valid')) ENABLE,
CHECK ( valid IN ('Invalid', 'Valid')) ENABLE,
CONSTRAINT "TBL_SERIAL_NUMBER_MASTER_CON" PRIMARY KEY ("SERIAL_NUMBER") ENABLE
) ;
CREATE OR REPLACE TRIGGER "TBL_SERIAL_NUMBER_MASTER_INTER" BEFORE
INSERT
ON tbl_serial_number_master FOR EACH ROW WHEN (
NEW.internal_record_id IS NULL
) BEGIN :NEW.internal_record_id := tbl_serial_number_master_inter.NEXTVAL;
END;
/
ALTER TRIGGER "TBL_SERIAL_NUMBER_MASTER_INTER" ENABLE;
I have already updated the SERIAL_NUMBER field using one table. Now I am trying to add more Serial Nos from another table. These other tables have duplicate and null value Serial Nos. Can you please advise how I can create the query to add unique Serial Nos that are already not in the TBL_SERIAL_NUMBER_MASTER.
Please assume following fields for the other table.
TABLE_SOURCE_B
ID :-PK
SERIAL_NUMBER
List item
Name

In your Master Table, 'Internal_Record_Id' has Not Null constraint. So I am inserting values of ID field of Source table into 'internal_record_id'.
Try the following query.
INSERT INTO
TBL_SERIAL_NUMBER_MASTER (INTERNAL_RECORD_ID,SERIAL_NUMBER)
SELECT ID,SERIAL_NUMBER
FROM TABLE_SOURCE_B B
WHERE B.SERIAL_NUMBER NOT IN(SELECT SERIAL_NUMBER
FROM TBL_SERIAL_NUMBER_MASTER);
Hope it helps!

Related

Error in primary key in sqlplus?

I am beginner in sql.I am using sqlplus to run the sql query .I used simple query but it shows an error like "MISSING RIGHT PARENTHESIS".My objective is to create the autoincrement primary key .Can anyone solve the error?Thanks in advance...
create table student(rollno int identity(1,1) primary key,
name varchar(20),marks int);
For Oracle, the rollno column could be defined as NUMBER(0010) and primary key.
Then you would need to add an ON INSERT trigger to populate rollno from a SEQUENCE. There are many samples of triggers and sequences on this site.
In oracle 12 you can use a identity column to automatically fill your ID
CREATE TABLE students
(
"ID" NUMBER GENERATED BY DEFAULT AS IDENTITY MINVALUE 1 MAXVALUE 9999999999
INCREMENT BY 1 START WITH 1 ,
"NAME" VARCHAR2(20),
"MARKS" NUMBER(2,0),
CONSTRAINT PK_STUDENTS PRIMARY KEY (ID) ENABLE
);
/
This creates a table without any triggers needed and automatically fills the id column (of not specified with a value) with the next number up to 99999...
If you're using oracle 11 and below, you need a trigger on insert and assign a value (custom_sequence.nextval) to the id column.
CREATE TABLE students
(
"ID" NUMBER(5,0) not null,
"NAME" VARCHAR2(20),
"MARKS" NUMBER(2,0),
CONSTRAINT PK_STUDENTS PRIMARY KEY (ID) ENABLE
);
/
CREATE SEQUENCE SEQ_STUDENTS INCREMENT BY 1 START WITH 1;
/
TRIGGER TC_students
before insert on students
for each row
begin
if (:new.id is null) then
select SEQ_students.nextval into :new.id from dual;
end if;
end;
/
And please use VARCHAR2.

how to check Composite Primary key before inserting new values

I have a table with multiple columns which consists of a composite primary key for three of them (columns customer_id,system_origin,policy_number).
The table is created as below :
Create table LOST_MEMBER_ACCESS_LOG (
Customer_id varchar2(20) NOT NULL,
System_Origin varchar2(20) NOT NULL,
Policy_Number varchar2(20) NOT_NULL,
PRIMARY_KEY(Customer_id,System_Origin, Policy_Number)
);
I have a requirement to write a stored proc which firsts checks if a row already exists for unique combination for customer_id,system_origin,policy_number then it updates the already existing row with the new values or else it inserts a new row.
What you're saying you want to do is:
if row exists then
update ...
else
insert ...
end if;
But there is easier way. Just do the update and check if any row was touched
update lost_member_access_log
set ...
where ... ;
if sql%rowcount = 0 then
insert into lost_member_access_log ...
end if;
MERGE is of course also an option.

Basic primary key / foreign key with constraint, sequence, trigger

Learner here in Oracle 11g. I'm having an issue with INSERTing some rows into two tables that are linked by a primary/foreign key relationship.
Basically I create a sequence to start with 1000 and increment by 1.
Then create a 'STORE' table with a ST_ID column
The ST_ID column is linked to the SEQUENCE with a TRIGGER.
Then I have an 'EMPLOYEE' table that has a EST_ID field that is a foreign key to the ST_ID column in the STORE table.
However, when I tried to insert rows I initially got a error saying EST_ID could not be null. So I created a sequence and trigger for EST_ID and now I'm getting an error saying the foreign key constraint is being violated.
I think that was maybe the wrong thing to do. Do I really want E_ID and EST_ID to be identical and how would I get that to happen? With some kind of trigger?
The actual code:
CREATE SEQUENCE "STORSEQ" MINVALUE 1000 MAXVALUE 9999 INCREMENT BY 1 START WITH 1000 NOCACHE NOORDER
NOCYCLE ;
CREATE TABLE "STORE"
( "ST_ID" CHAR(4) NOT NULL ENABLE,
"STADDR_ID" CHAR(4) NOT NULL ENABLE,
CONSTRAINT "STORE_PK" PRIMARY KEY ("ST_ID") ENABLE
) ;
CREATE TABLE "EMPLOYEE"
( "E_ID" CHAR(8) NOT NULL ENABLE,
"EF_NAME" VARCHAR2(20) NOT NULL ENABLE,
"EL_NAME" VARCHAR2(20) NOT NULL ENABLE,
"EST_ID" CHAR(4) NOT NULL ENABLE,
CONSTRAINT "EMPLOYEE_PK" PRIMARY KEY ("E_ID") ENABLE
) ;
alter table "EMPLOYEE" add CONSTRAINT "EMPLOYEE_CON" foreign key ("EST_ID") references
"STORE" ("ST_ID")
/
CREATE OR REPLACE TRIGGER "BI_STORE"
before insert on "STORE"
for each row
begin
if :NEW."ST_ID" is null then
select "STORSEQ".nextval into :NEW."ST_ID" from dual;
end if;
end;
/
At the moment my INSERT code looks like this:
INSERT INTO STORE
(ST_ID, STADDR_ID)
VALUES
(DEFAULT, DEFAULT);
INSERT INTO EMPLOYEE
(EF_NAME, EL_NAME)
VALUES
('James', 'Smith');
When you try to insert data into table that has foreign key reference, it will not get value for id automatically, you need to pass that value.
You can do this:
declare
v_store_id integer;
begin
INSERT INTO STORE (ST_ID, STADDR_ID) VALUES (DEFAULT, DEFAULT)
RETURNING ST_ID INTO v_Store_id;
INSERT INTO EMPLOYEE (EF_NAME, EL_NAME, EST_ID)
VALUES ('James', 'Smith', v_store_id);
end;
You can also insert id in store id table without trigger using this
declare
v_store_id integer;
begin
INSERT INTO STORE (ST_ID, STADDR_ID) VALUES ("STORSEQ".nextval, DEFAULT)
RETURNING ST_ID INTO v_Store_id;
INSERT INTO EMPLOYEE (EF_NAME, EL_NAME, EST_ID)
VALUES ('James', 'Smith', v_store_id);
end

Trigger with current date query/where clause

we want to create a trigger which checks if a new measurement (=messung) point lies within the current glacier shape (=umriss).
are tables look like this:
glacier shape (=Umriss)
create table umriss
(
umr_nr number (4) not null,
umr_datum date,
GLST_ID number (4) not null,
shape mdsys.sdo_geometry,
GLETSCHER_ID number (3) not null
)
;
alter table umriss
add constraint umriss_glst_pk
primary key (umr_nr, GLST_ID, GLETSCHER_ID)
;
ALTER TABLE umriss
ADD CONSTRAINT umriss_gletscherstand_fk
FOREIGN KEY (GLST_ID, GLETSCHER_ID)
REFERENCES GLETSCHERSTAND(GLST_ID, GLETSCHER_ID);
new measurement (=Messung)
CREATE TABLE MESSUNG
(
MESS_NR number (4) not null,
MESS_DAT date,
MESS_AKK number (20) NOT NULL,
MESS_SCHMELZ number (20) NOT NULL,
SHAPE mdsys.sdo_geometry,
MESS_BILD blob,
KMPGN_NR NUMBER (4) NOT NULL
);
ALTER TABLE MESSUNG
ADD CONSTRAINT messung_pk
PRIMARY KEY (MESS_NR);
ALTER TABLE MESSUNG
ADD CONSTRAINT messung_messkampagne_fk
FOREIGN KEY (KMPGN_NR)
REFERENCES MESSKAMPAGNE(KMPGN_NR);
Trigger
CREATE OR REPLACE
TRIGGER MESSUNG_in_UMRISS_TRI
BEFORE INSERT OR UPDATE ON MESSUNG
FOR EACH ROW
DECLARE
num_check NUMBER;
BEGIN
SELECT COUNT (*) INTO num_check
FROM UMRISS u
WHERE mdsys.sdo_contains (u.shape, :NEW.point) = 'TRUE';
IF num_check <> 1
THEN
RAISE_APPLICATION_ERROR (=20500, 'Messung in keinem Umriss')
END IF;
END;
How do we iplement the function so the trigger only checks within the most curretn glacier shape?
Thanks for your help!
This will return the one row fron UMRISS which matches the most recent date in the table.
SELECT COUNT (*) INTO num_check
FROM UMRISS u
WHERE mdsys.sdo_contains (u.shape, :NEW.point) = 'TRUE'
AND u.umr_datum = ( select max(d.;umr_datum) from UMRISS d );
This sort of query is the price for keeping historical data in teh same table as the current record.
it seems that POINT ist not defined in your example?
However, you might consider a check constraint because a trigger would only be enforced when a MESSUNG record is inserted or updated, but not when UMRISS is changed
alter table MESSUNG add constraint MESSUNG_CC_CONTAINS check(mdsys.sdo_contains (shape, point) = 'TRUE')
In case you're frequently updating the UMRISS records it might not be feasable at all to enforce such a constraint because Oracle would have to check all MESSUNG records when UMRISS is updated or deleted. Perhaps consider an additional mapping table between MESSUNG and UMRISS that you can update separately.

Autoincrement Primary key in Oracle database

I would like to achieve an identity or auto-incrementing value in a column ala SQL Server:
CREATE TABLE RollingStock
(
Id NUMBER IDENTITY(1,1),
Name Varchar2(80) NOT NULL
);
How can this be done?
As Orbman says, the standard way to do it is with a sequence. What most people also do is couple this with an insert trigger. So, when a row is inserted without an ID, the trigger fires to fill out the ID for you from the sequence.
CREATE SEQUENCE SEQ_ROLLINGSTOCK_ID START WITH 1 INCREMENT BY 1 NOCYCLE;
CREATE OR REPLACE TRIGGER BI_ROLLINGSTOCK
BEFORE INSERT ON ROLLINGSTOCK
REFERENCING OLD AS OLD NEW AS NEW
FOR EACH ROW
WHEN (NEW.ID IS NULL)
BEGIN
select SEQ_ROLLINGSTOCK_ID.NEXTVAL
INTO :NEW.ID from dual;
END;
This is one of the few cases where it makes sense to use a trigger in Oracle.
If you really don't care what the primary key holds, you can use a RAW type for the primary key column which holds a system-generated guid in binary form.
CREATE TABLE RollingStock
(
ID RAW(16) DEFAULT SYS_GUID() PRIMARY KEY,
NAME VARCHAR2(80 CHAR) NOT NULL
);