Can not delete Metadata entry in Spatial DB - oracle

I am trying to a spatial data table in my db using :
CREATE TABLE building (buildid VARCHAR(15) PRIMARY KEY, buildname VARCHAR(50),numpoint NUMBER,points SDO_GEOMETRY);
CREATE INDEX building_spatial_idx ON building(points) INDEXTYPE IS MDSYS.SPATIAL_INDEX;
INSERT INTO USER_SDO_GEOM_METADATA(TABLE_NAME,COLUMN_NAME,DIMINFO,SRID)
VALUES (
'building',
'points',
SDO_DIM_ARRAY( --820*580 grid
SDO_DIM_ELEMENT('X', 0, 820, 1),
SDO_DIM_ELEMENT('Y', 0, 580, 1)
),
NULL --SRID
);
When I executed it for the first time it did not give any errors but afterwords it is giving error
insert into user_sdo_geom_metadata values
*
ERROR at line 1:
ORA-00001: unique constraint (MDSYS.UNIQUE_LAYERS) violated
ORA-06512: at "MDSYS.SDO_GEOM_TRIG_INS1", line 27
ORA-04088: error during execution of trigger 'MDSYS.SDO_GEOM_TRIG_INS1'
Is it happening because am trying to give meta-data for same table again.
Or is there any other reason. How can i delete all the index,metadata,table at a single go and remove this error.

A new Schema creation solved the problem,

Related

Trigger to raise raise an application error with a meaningful message if og_id refers to a cancelled Olympic Game

These are the following tables I have created:
CREATE TABLE Country
(
country_id NUMBER(3) PRIMARY KEY,
country_name VARCHAR(3) UNIQUE NOT NULL,
CONSTRAINT check_country_id CHECK (country_id > 0)
);
CREATE TABLE OG_Type
(
og_type_id NUMBER(3) PRIMARY KEY,
og_type_title VARCHAR(20) UNIQUE NOT NULL
);
CREATE TABLE Olympic_Game
(
og_id NUMBER(3) PRIMARY KEY,
og_type_id NUMBER(3) NOT NULL,
og_year NUMBER(4) NOT NULL,
og_website VARCHAR(150),
og_cancel VARCHAR(1) NOT NULL,
country_id NUMBER(3) NOT NULL,
CONSTRAINT check_og_id CHECK (og_id > 0),
CONSTRAINT check_og_year_og_type UNIQUE (og_type_id, og_year),
CONSTRAINT fk_og_type_id FOREIGN KEY(og_type_id) REFERENCES OG_Type(og_type_id),
CONSTRAINT fk_country_id FOREIGN KEY(country_id) REFERENCES Country(country_id)
);
CREATE TABLE Sport
(
sport_id NUMBER(3) PRIMARY KEY,
sport_title VARCHAR(100) UNIQUE NOT NULL,
CONSTRAINT check_sport_id CHECK (sport_id > 0)
);
CREATE TABLE Event
(
event_id NUMBER(6) PRIMARY KEY,
sport_id NUMBER(3) NOT NULL,
og_id NUMBER(3) NOT NULL,
event_title VARCHAR(100) NOT NULL,
event_team VARCHAR(1) NOT NULL,
no_per_team NUMBER(2) NOT NULL,
event_gender VARCHAR(1) NOT NULL,
CONSTRAINT check_event_id CHECK (event_id > 0),
CONSTRAINT check_event_title_sport_id_og_id_event_team_event_gender UNIQUE (event_title, sport_id, og_id, event_team, event_gender),
CONSTRAINT check_event_team CHECK (event_team IN ('Y','N')),
CONSTRAINT check_event_team_no_per_team CHECK ((event_team='N' AND no_per_team=1) OR (event_team='Y' AND no_per_team>1)),
CONSTRAINT check_event_gender CHECK (event_gender IN ('M','F')),
CONSTRAINT fk_sport_id FOREIGN KEY(sport_id) REFERENCES Sport(sport_id),
CONSTRAINT fk_og_id FOREIGN KEY(og_id) REFERENCES Olympic_Game(og_id)
);
After creating these 4 tables, I have inserted the values for these 4 tables:
insert into country(country_id,country_name) values (country_seq.nextval,'FRA');
insert into country(country_id,country_name) values (country_seq.nextval,'GBR');
insert into country(country_id,country_name) values (country_seq.nextval,'GRE');
insert into country(country_id,country_name) values (country_seq.nextval,'USA');
insert into og_type(og_type_id, og_type_title) values(og_type_seq.nextval,'Summer');
insert into og_type(og_type_id, og_type_title) values(og_type_seq.nextval,'Winter');
insert into og_type(og_type_id, og_type_title) values(og_type_seq.nextval,'Special');
insert into og_type(og_type_id, og_type_title) values(og_type_seq.nextval,'Youth');
insert into og_type(og_type_id, og_type_title) values(og_type_seq.nextval,'Senior');
insert into olympic_game(og_id,og_type_id,og_year,og_website,og_cancel,country_id) values(og_seq.nextval,1,1896,null,'N',3);
insert into olympic_game(og_id,og_type_id,og_year,og_website,og_cancel,country_id) values(og_seq.nextval,1,1900,null,'N',1);
insert into olympic_game(og_id,og_type_id,og_year,og_website,og_cancel,country_id) values(og_seq.nextval,1,1904,null,'N',4);
insert into olympic_game(og_id,og_type_id,og_year,og_website,og_cancel,country_id) values(og_seq.nextval,1,1908,'op1908.org','N',2);
insert into olympic_game(og_id,og_type_id,og_year,og_website,og_cancel,country_id) values(og_seq.nextval,2,1924,null,'N',1);
insert into olympic_game(og_id,og_type_id,og_year,og_website,og_cancel,country_id) values(og_seq.nextval,1,1944,null,'Y',2);
insert into olympic_game(og_id,og_type_id,og_year,og_website,og_cancel,country_id) values(og_seq.nextval,3,1944,null,'Y',2);
insert into olympic_game(og_id,og_type_id,og_year,og_website,og_cancel,country_id) values(og_seq.nextval,4,1944,null,'Y',2);
insert into olympic_game(og_id,og_type_id,og_year,og_website,og_cancel,country_id) values(og_seq.nextval,5,1944,null,'Y',2);
insert into olympic_game(og_id,og_type_id,og_year,og_website,og_cancel,country_id) values(og_seq.nextval,1,2012,'https://www.olympic.org/london-2012','N',2);
insert into sport(sport_id,sport_title) values(sport_seq.nextval, 'Track and Field');
insert into sport(sport_id,sport_title) values(sport_seq.nextval, 'Tennis');
insert into sport(sport_id,sport_title) values(sport_seq.nextval, 'Speed Skating');
insert into event(event_id,sport_id,og_id,event_title,event_team,no_per_team,event_gender) values(event_seq.nextval,1,1,'100m','N',1,'M');
insert into event(event_id,sport_id,og_id,event_title,event_team,no_per_team,event_gender) values(event_seq.nextval,2,1,'Double','Y',2,'M');
insert into event(event_id,sport_id,og_id,event_title,event_team,no_per_team,event_gender) values(event_seq.nextval,1,2,'200m','N',1,'M');
insert into event(event_id,sport_id,og_id,event_title,event_team,no_per_team,event_gender) values(event_seq.nextval,2,2,'Single','N',1,'M');
insert into event(event_id,sport_id,og_id,event_title,event_team,no_per_team,event_gender) values(event_seq.nextval,1,3,'400m','N',1,'F');
insert into event(event_id,sport_id,og_id,event_title,event_team,no_per_team,event_gender) values(event_seq.nextval,1,3,'100m','N',1,'F');
insert into event(event_id,sport_id,og_id,event_title,event_team,no_per_team,event_gender) values(event_seq.nextval,1,4,'1500m','N',1,'F');
insert into event(event_id,sport_id,og_id,event_title,event_team,no_per_team,event_gender) values(event_seq.nextval,3,5,'800m','N',1,'F');
insert into event(event_id,sport_id,og_id,event_title,event_team,no_per_team,event_gender) values(event_seq.nextval,1,10,'100m','N',1,'M');
insert into event(event_id,sport_id,og_id,event_title,event_team,no_per_team,event_gender) values(event_seq.nextval,1,10,'100m','N',1,'F');
Now this is the question:
Create a trigger called TR_event_on_cancelled_og. This trigger fires before inserting or updating a row in the Event table. The trigger should raise an application error with a meaningful message if og_id refers to a cancelled Olympic Game.
Now this is the solution I came up with:
CREATE OR REPLACE TRIGGER TR_event_on_cancelled
BEFORE INSERT OR UPDATE
ON Event
FOR EACH ROW
BEGIN
DECLARE
v_og_cancel Olympic_Game.og_cancel%TYPE;
BEGIN
SELECT og_cancel INTO V_og_cancel
FROM Olympic_Game, Event
WHERE Olympic_Game.og_id = Event.og_id
AND Olympic_Game.og_id = :NEW.og_id;
IF (v_og_cancel = 'N')
THEN
RAISE_APPLICATION_ERROR(-20001, 'This Olympic Game is cancelled already');
END IF;
END;
END;
Trigger TR_EVENT_ON_CANCELLED compiled
The trigger is compiled successfully but the problem is when I was trying to test the trigger I got the following error messages:
insert into event(event_id,sport_id,og_id,event_title,event_team,no_per_team,event_gender) values(event_seq.nextval,1,8,'400m','N',1,'F');
Error report -
SQL Error: ORA-01403: no data found
ORA-06512: at "OG_JC480454.TR_EVENT_ON_CANCELLED", line 5
ORA-04088: error during execution of trigger 'OG_JC480454.TR_EVENT_ON_CANCELLED'
01403. 00000 - "no data found"
*Cause: No data was found from the objects.
*Action: There was no data from the objects which may be due to end of fetch.
insert into event(event_id,sport_id,og_id,event_title,event_team,no_per_team,event_gender) values(event_seq.nextval,1,2,'400m','N',1,'F');
Error report -
SQL Error: ORA-01422: exact fetch returns more than requested number of rows
ORA-06512: at "OG_JC480454.TR_EVENT_ON_CANCELLED", line 5
ORA-04088: error during execution of trigger 'OG_JC480454.TR_EVENT_ON_CANCELLED'
01422. 00000 - "exact fetch returns more than requested number of rows"
*Cause: The number specified in exact fetch is less than the rows returned.
*Action: Rewrite the query or change number of rows requested
Where did I exactly go wrong ? ...
It would be really helpful if the trigger solution code is provided.
I think your problem is that your trigger code is selecting from EVENT. It doesn't need to do this because the rule applies only to the current event you're inserting or updating.
So:
SELECT og_cancel INTO V_og_cancel
FROM Olympic_Game
WHERE Olympic_Game.og_id = :NEW.og_id;
Incidentally, the next test looks wrong:
IF (v_og_cancel = 'N')
Unless you're using Y/N flags in an odd manner this would be testing if the Games have not been cancelled. Surely that should be = 'Y'?
" I want to get this error message"
I have created an Oracle LiveSQL with your data and my version of the trigger. Find it here (but you will need an OTN account to look at it).
When I attempt this INSERT ...
insert into event(event_id,sport_id,og_id,event_title,event_team,no_per_team,event_gender)
values(event_seq.nextval,2,9,'Double','Y',2,'M');
it fails on
ORA-20001: This Olympic Game is cancelled already
Quite rightly, because the games where og_id = 9 has og_cancel='Y'.
Now you say you're getting ORA-20977: the game was cancelled. That's a user-defined error (in the range -20999 to -20000. So it's some part of your codebase which is hurling it.
If you don't know what part it is you will need to dig into your data dictionary. I can't solve that for you. But here's a thought: have you got more than one trigger on the table? Your homework says to create a trigger called TR_event_on_cancelled_og but the code you published does CREATE OR REPLACE TRIGGER TR_event_on_cancelled. Perhaps you previously created a trigger with the other name, and that's what is raising the ORA-20977.

SQL Error: ORA-04091: table is mutating while updating by a trigger

i am new to oracle , i am developing a hospital management system , i have this table to store patients :
create table patients(
p_id number not null primary key,
p_fullname full_name_ty,
p_gender char,
de_no number,
p_entry date ,
Diagnosis varchar2(25),
p_exit date,
constraint pdf foreign key (de_no) references department(dep_no)
);
where p_entry is the date when a patient enters the hospital , i made a trigger that calculates the residency time in the hospital on after the upadate of the (p_exit) date for the patient (setting this date means that the patient has left the hospital) , the trigger will simply calculate the difference between the two dates , and print it , here is the code of the trigger :
create or replace
trigger period_trig before update of p_exit on patients for each row
DECLARE
period Number(3);
enterr DATE;
exitt DATE;
BEGIN
enterr := :old.P_ENTRY;
exitt:= :NEW.P_EXIT;
Period :=exitt-enterr;
DBMS_OUTPUT.PUT_LINE('Duration:'||period);
update patients SET RESIDENCY= Period where P_ID = :old.P_ID;
end period_trig
put when i test the trigger and use an update statement like this :
update patients set p_exit = to_date('01/02/2001','dd/mm/yyyy') where p_id = 2;
and run it i get this error :
Error starting at line 1 in command:
update patients set p_exit = to_date('01/02/2001','dd/mm/yyyy') where p_id = 2
Error report:
SQL Error: ORA-04091: table SEM.PATIENTS is mutating, trigger/function may not see it
ORA-06512: at "SEM.UPDATEPAT", line 5
ORA-06512: at "SEM.PERIOD_TRIG", line 10
ORA-04088: error during execution of trigger 'SEM.PERIOD_TRIG'
04091. 00000 - "table %s.%s is mutating, trigger/function may not see it"
*Cause: A trigger (or a user defined plsql function that is referenced in
this statement) attempted to look at (or modify) a table that was
in the middle of being modified by the statement which fired it.
*Action: Rewrite the trigger (or function) so it does not read that table.
Error starting at line 1 in command:
update patients set p_exit = to_date('01/02/2001','dd/mm/yyyy') where p_id = 2
Error report:
SQL Error: ORA-04091: table SEM.PATIENTS is mutating, trigger/function may not see it
ORA-06512: at "SEM.PERIOD_TRIG", line 11
ORA-04088: error during execution of trigger 'SEM.PERIOD_TRIG'
04091. 00000 - "table %s.%s is mutating, trigger/function may not see it"
*Cause: A trigger (or a user defined plsql function that is referenced in
this statement) attempted to look at (or modify) a table that was
in the middle of being modified by the statement which fired it.
*Action: Rewrite the trigger (or function) so it does not read that table.
can anyone tell me how to fix it ? and thanks so much ..
You are modifying the very same table in the trigger that is currently being modified. As they error tells you:
*Cause: A trigger (or a user defined plsql function that is referenced in
this statement) attempted to look at (or modify) a table that was
in the middle of being modified by the statement which fired it.
*Action: Rewrite the trigger (or function) so it does not read that table.
There is actually no need in updating the table again, you can simply use a virtual column directly on the table that makes the entire trigger redundant:
CREATE TABLE patients(
p_id NUMBER NOT NULL PRIMARY KEY,
p_fullname VARCHAR2(255),
p_gender CHAR(1),
de_no NUMBER,
p_entry DATE,
Diagnosis VARCHAR2(25),
p_exit DATE,
RESIDENCY NUMBER GENERATED ALWAYS AS (p_exit-p_entry)
);
insert into patients (p_id, p_fullname, p_gender, de_no, p_entry, diagnosis) values (1, 'GVENZL', 'M', 1234, SYSDATE-1, 'healthy' );
commit;
select p_fullname, residency from patients;
update patients set p_exit = sysdate;
commit;
select p_fullname, residency from patients;

Trouble adding metadata to a table in Oracle

I created a table in Oracle with this code:
CREATE TABLE Roads (
TYPE VARCHAR2(40),
ADMN_CLASS VARCHAR2(20),
TOLL_RD VARCHAR2(10),
RTE_NUM1 VARCHAR2(3),
RTE_NUM2 VARCHAR2(3),
ROUTE VARCHAR2(40),
LOCATION MDSYS.SDO_GEOMETRY);
Then I wanted to add metadata to the LOCATION column which will hold the geometry:
INSERT INTO USER_SDO_GEOM_METADATA
(TABLE_NAME, COLUMN_NAME, DIMINFO, SRID)
VALUES
('ROADS', 'LOCATION',
MDSYS.SDO_DIM_ARRAY
( MDSYS.SDO_DIM_ELEMENT('X', -180, 180, 0.5),
MDSYS.SDO_DIM_ELEMENT('Y', -90, 90, 0.5)
),
8256
);
However, I get an error:
Error report -
SQL Error: ORA-13223: duplicate entry for ROADS.LOCATION in SDO_GEOM_METADATA
ORA-06512: at "MDSYS.MD", line 1723
ORA-06512: at "MDSYS.MDERR", line 17
ORA-06512: at "MDSYS.SDO_GEOM_TRIG_INS1", line 48
ORA-04088: error during execution of trigger 'MDSYS.SDO_GEOM_TRIG_INS1'
13223. 00000 - "duplicate entry for %s in SDO_GEOM_METADATA"
*Cause: There are duplicate entries for the given table and column
value pair in the USER_SDO_GEOM_METADATA view.
*Action: Check that the specified table and geometry column names
are correct. There should be only one entry per table, geometry
column pair in the USER_SDO_GEOM_METADATA view.
I am not sure why it says there are duplicate values because I have not created this table before. It also tells me to make sure that table and column name is correct and they are.
I've created your table and executed your insert statement OK.
Once executed again, I was able to reproduce your problem.
The error "SQL Error: ORA-13223: duplicate entry for ROADS.LOCATION in SDO_GEOM_METADATA" definitely points to duplicate data.
This trigger MDSYS.SDO_GEOM_TRIG_INS1 just performs a count(*) validation on the following MDSYS table and raise the -13223 exception when rowcount is != 0 .
SQL> desc mdsys.SDO_GEOM_METADATA_TABLE
Name Null? Type
----------------------------------------- -------- ----------------------------
SDO_OWNER NOT NULL VARCHAR2(32)
SDO_TABLE_NAME NOT NULL VARCHAR2(32)
SDO_COLUMN_NAME NOT NULL VARCHAR2(1024)
SDO_DIMINFO MDSYS.SDO_DIM_ARRAY
SDO_SRID NUMBER
Query mdsys.SDO_GEOM_METADATA_TABLE in order to validate its contents. You should find the duplicate record:
SQL> select * from mdsys.SDO_GEOM_METADATA_TABLE ;
USER1
ROADS
LOCATION
SDO_DIM_ARRAY(SDO_DIM_ELEMENT('X', -180, 180, .5), SDO_DIM_ELEMENT('Y', -90, 90,
.5))
8256
To workaround this issue just delete that record from mdsys.SDO_GEOM_METADATA_TABLE.
I think the problem is because some space characters on the column_name.
COR_NB_SC_LON,COR_CD_EW_ LON
I have fixed it and it works.
insert into user_sdo_geom_metadata (table_name, column_name, diminfo, srid)
values (
'COORD_REF',
'myuser.CONVERT_DMS_TO_GEOM(COR_NB_DG_LON,COR_NB_MN_LON,COR_NB_SC_LON,COR_ CD_EW_LON,COR_NB_DG_LAT,COR_NB_MN_LAT,COR_NB_SC_LAT,COR_CD_NS_LAT)',
sdo_dim_array (
sdo_dim_element('long', -180.0, 180.0, 0.5),
sdo_dim_element('lat', -90.0, 90.0, 0.5)
),
4326
);
commit;

Triggering after an update or delete on a FK constraint between 2 tables in oracle

I have the following tables:
create table emp_test_lucian as select employee_id,last_name,first_name,department_id from employees;
ALTER TABLE emp_test_lucian
ADD PRIMARY KEY (employee_id);
create table dept_test_lucian as select department_id,department_name from departments_copy;
ALTER TABLE dept_test_lucian
ADD PRIMARY KEY (department_id);
On this tables I want to perform different operations for example: If a department gets deleted (from dept_test_lucian) I will delete all the rows in emp_test_lucian that have that department id with a trigger. This works fine when no fk between the 2 is declared with the following code :
CREATE OR REPLACE TRIGGER triger5
BEFORE UPDATE or DELETE on dept_test_lucian
FOR EACH ROW
BEGIN
IF DELETING then
delete
from emp_test_lucian
where department_id = :OLD.department_id;
else if UPDATING('department_id') then
UPDATE emp_test_lucian
set department_id = :NEW.department_id
where department_id = :OLD.department_id;
END IF;
END IF;
END;
/
What can I add to the code above to work even if I have a fk between the 2 tables like so:
ALTER TABLE emp_test_lucian
ADD CONSTRAINT fk_dep_id FOREIGN KEY(department_id) REFERENCES dept_test_lucian(department_id);
the current code returns :
Error report:
ORA-00001: unique constraint (C##LABORATOR.SYS_C009994) violated
ORA-06512: at line 2
00001. 00000 - "unique constraint (%s.%s) violated"
*Cause: An UPDATE or INSERT statement attempted to insert a duplicate key.
For Trusted Oracle configured in DBMS MAC mode, you may see
this message if a duplicate entry exists at a different level.
*Action: Either remove the unique restriction or do not insert the key.
You need to make clear what table is the 'parent' and what table is the 'child'.
In your example:
- Parent: dept_test_lucian
- Child: emp_test_lucian
Lets call 'dept_test_lucian': TableA
Lets call 'emp_test_lucian': TableB
I come to this conclusion since there is a CONSTRAINT on TableB.department_id" that can only have a value that exists
in "TableA.department_id"
The error message tells you that there is a 'primary key being vialated'.
Primary keys on you tables are:
- "TableA.employee_id"
- "TableB.department_id"
Apparently you are trying to insert a value in one of these columns where that value already exists in.
If '1' is already existing in "TableA.employee_id" you would get such an error.
What I also see in your trigger is:
You have a BEFORE UPDATE Trigger.
So the Trigger looks if there is an UPDATE comming on "TableA" (Parent).
Then you try to UPDATE "TableB" (child) first.
This could be tricky, since "TableB.department_id" can only have values that exist in "TableA.department_id".
If the new UPDATE value doesn't exist in "TableA.department_id", you can not UPDATE that value in "TableB.department_id"

can not update user_sdo_geom_metadata when creating spatial database in oracle

i was using the oracle 11g and try to create a spatial database, i just copied the sample code from oracle document
but when it comes to update the metadata part, it gave a duplicate entry error, and i tried delete from user_sdo_geom_metadata and it didnot give any error, and then tried to insert again, still got the duplicate entry error. I also tried select * from user_sdo_geom_metadata but got nothing.
any one have idea why? thanks
THE sample code:
CREATE TABLE cola_markets (
mkt_id NUMBER PRIMARY KEY,
name VARCHAR2(32),
shape SDO_GEOMETRY);
INSERT INTO cola_markets VALUES(
1,
'cola_a',
SDO_GEOMETRY(
2003, -- two-dimensional polygon
NULL,
NULL,
SDO_ELEM_INFO_ARRAY(1,1003,3), -- one rectangle (1003 = exterior)
SDO_ORDINATE_ARRAY(1,1, 5,7) -- only 2 points needed to
-- define rectangle (lower left and upper right) with
-- Cartesian-coordinate data
));
INSERT INTO user_sdo_geom_metadata
(TABLE_NAME,
COLUMN_NAME,
DIMINFO,
SRID)
VALUES (
'cola_markets',
'shape',
SDO_DIM_ARRAY( -- 20X20 grid
SDO_DIM_ELEMENT('X', 0, 20, 0.005),
SDO_DIM_ELEMENT('Y', 0, 20, 0.005)
),
NULL -- SRID
);
error cause: there are duplicate entries for the give table and column value pair in the user_sdo_geom_metadata view.
Just to be sure, what does the following show ?
SELECT * FROM USER_SDO_GEOM_METADATA;
Object names in dictionary views are stored in uppercase. So if you want to remove existing entries from the spatial metadata you need to do this (notice the uppper case table name):
DELETE FROM USER_SDO_GEOM_METADATA WHERE TABLE_NAME = 'COLA_MARKETS';
COMMIT;

Resources