I am trying to create a table in apex5 with reference having foreign key from another table and that foreign key column is populated. But to create is returning the error ORA- 00922: missing or invalid option, already checked and not noticed any error naming what can is going wrong? The following code:
CREATE TABLE "IMAGEM_ICONE_SISTEMA"
( "COD" NUMBER NOT NULL ENABLE,
"COD_SISTEMA" NUMBER(6,0) NOT NULL ENABLE,
"NOME" VARCHAR2(55),
"ARQUIVO_IMAGEM" BLOB,
"MIMETYPE" VARCHAR2(255),
"FILENAME" VARCHAR2(400),
"IMG_LAST_UPDATE" TIMESTAMP (6) WITH LOCAL TIME ZONE,
"UPDATED_BY" VARCHAR2(55),
"TEXTO_DESCRICAO" VARCHAR2(55),
"LINK" VARCHAR2(2000),
"NUM_ORDEM" NUMBER(6,0),
CONSTRAINT "IMAGEM_ICONE_SISTEM_PK" PRIMARY KEY ("COD") USING INDEX ENABLE)
/
ALTER TABLE "IMAGEM_ICONE_SISTEMA" ADD CONSTRAINT "IMAGEM_ICONE_SISTEMA_FK" FOREIGN KEY ("COD_SISTEMA")
REFERENCES "APEX_SISTEMA" ("COD") ON DELETE CASCADE ENABLE
/
CREATE INDEX "IMAGEM_ICONE_SISTEMA_I2" ON "IMAGEM_ICONE_SISTEMA" ("COD_SISTEMA")
/
CREATE OR REPLACE EDITIONABLE TRIGGER "BI_IMAGEM_ICONE_SISTEMA" before insert or update on IMAGEM_ICONE_SISTEMA
for each row
begin
if :new.COD is null then
select to_number(sys_guid(),'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX') into :new.cod from dual;
end if;
if inserting then
:new.img_last_update := localtimestamp;
:new.updated_by := nvl(wwv_flow.g_user,user);
elsif updating and :new.filename is not null and nvl(dbms_lob.getlength(:new.arquivo_imagem),0) > 15728640 then raise_application_error(-20000, 'O tamanho do arquivo enviado foi maior do que 15MB . Faça o upload de um arquivo de tamanho menor.');
end if;
if (inserting or updating) and :new.filename is not null and nvl(:new.mimetype,'NULL') not like 'image%' then
raise_application_error(-20000, 'O arquivo enviado não é uma imagem. Faça o upload de um arquivo de imagem.');
end if;
if inserting or updating then
:new.img_last_update := localtimestamp;
:new.updated_by := nvl(wwv_flow.g_user,user);
end if;
end;
/
ALTER TRIGGER "BI_IMAGEM_ICONE_SISTEMA" ENABLE
/
Related
On table "Types", the rows order shall be controled by the field "ordem".
After any data modifications(Delete, Insert or Update), the others rows should be ajusted to assure correct exbitions of the content.
To implement this funcionality, I tried to code a trigger to correct the values in two similar ways (I, II).
CREATE TABLE TYPES (
ID NUMBER PRIMARY KEY,
ARG_1 VARCHAR2(20) NOT NULL,
ARG_2 VARCHAR2(20) NOT NULL,
ORDEM NUMBER NOT NULL
);
-----------------------------------------------
-- I
-----------------------------------------------
CREATE OR REPLACE TRIGGER TGR_TYPES
AFTER INSERT OR UPDATE OR DELETE ON TYPES
DECLARE
V_NORDEM NUMBER := NEW.ORDEM;
CURSOR C_TYPES IS
SELECT ID, ORDEM
FROM TYPES
WHERE ORDEM >= V_NORDEM;
BEGIN
IF UPDATING OR INSERTING THEN
BEGIN
FOR R_TYPE IN C_TYPES LOOP
UPDATE TYPEA SET ORDEM = (ORDEM + 1) WHERE ID = R_TYPE.ID;
END LOOP;
END;
ELSE
DECLARE V_ORDEM NUMBER := 0;
BEGIN
FOR R_TYPE IN C_TYPES LOOP
UPDATE OSP_TP_ADDR_COMPLEMENTOS SET ORDEM = (V_ORDEM + 1) WHERE ID = R_COMPLEMENTO.ID;
END LOOP;
END;
END IF;
END;
/*
ERROR ON COMPILE:
ORA-04082: referências NEW ou OLD não permitidas nos gatilhos de nível de tabela
04082. 00000 - "NEW or OLD references not allowed in table level triggers"
*Cause: The trigger is accessing "new" or "old" values in a table trigger.
*Action: Remove any new or old references.
*/
-----------------------------------------------
-- II
-----------------------------------------------
CREATE OR REPLACE
TRIGGER TRG_TYPES
AFTER INSERT OR UPDATE OR DELETE ON TYPES
FOR EACH ROW
BEGIN
IF UPDATING OR INSERTING THEN
BEGIN
FOR TP IN (
SELECT *
FROM TYPES
WHERE ORDEM >= :NEW.ORDEM
) LOOP
UPDATE TYPES SET ORDEM = (ORDEM + 1) WHERE ID = TP.ID;
COMMIT;
END LOOP;
END;
ELSE
DECLARE V_ORDEM NUMBER := 0;
BEGIN
FOR TP IN (
SELECT *
FROM TYPES
ORDER BY ORDEM
) LOOP
UPDATE TYPES SET ORDEM = (V_ORDEM + 1) WHERE ID = TP.ID;
END LOOP;
END;
END IF;
END;
/*
ERROR ON UPDATE:
UPDATE TYPES
SET ORDEM = 14
WHERE ID=26
Relatório de erros -
ORA-04091: a tabela TYPES é mutante; talvez o gatilho/função não possa localizá-la
ORA-06512: em "", line 9
ORA-04088: erro durante a execução do gatilho ''
*/
I expect one solution to assure the trigger operation or other approach to the integrity of the order field. I have thinking about tring the Index-Organized Table structure, but not sure.
hello I want to create a trigger in a nested table to verify that upon entering an author this is NOT under 18 years old. but it does not work
I tried this.
SET SERVEROUTPUT ON
CREATE OR REPLACE TRIGGER CHEQ_EDAD_AUTOR4
BEFORE INSERT OR UPDATE ON libros
FOR EACH ROW
DECLARE
ANIO_ACTUAL INT := TO_NUMBER(SYSDATE,'YYYY');
BEGIN
DBMS_OUTPUT.PUT_LINE('año actual' || TO_CHAR(ANIO_ACTUAL) - 'año nacimiento' || TO_CHAR(:NEW.autor.nacimiento.anio) );
IF ( ANIO_ACTUAL - :NEW.autor.nacimiento.anio ) <18 THEN
RAISE_APPLICATION_ERROR(-20001,'El autor debe ser mayor de 18 años.');
END IF;
END;
But when i create the trigger sql developer says
Error(4,9): PL/SQL: Statement ignored Error(4,110): PLS-00302:
component 'NACIMIENTO' must be declared Error(6,9): PL/SQL: Statement
ignored Error(6,40): PLS-00302: component 'NACIMIENTO' must be
declared
--Autor
CREATE TYPE nacimiento_type AS OBJECT(
ciudad VARCHAR2(20),
pais VARCHAR2(20),
anio INT
)
/
CREATE TYPE autores_type AS OBJECT(
id_autor NVARCHAR2(20),
nombres nombres_type,
nacimiento nacimiento_type
)
/
CREATE TYPE autores_tab AS TABLE OF autores_type;
/
--------------------------------------------------------------------------------
--Libro
CREATE TYPE libros_type AS OBJECT(
id_libro INT,
titulo NVARCHAR2(50),
editorial NVARCHAR2(50),
anio INT,
area NVARCHAR2(50),
autor autores_tab
)
/
CREATE TABLE libros OF libros_type(
id_libro PRIMARY KEY
)NESTED TABLE autor STORE AS autores_nested;
/
The inserted data are:
--Insertando libros
INSERT INTO LIBROS VALUES (1,'Base de datos relacionales','Rama',2001,'Informática',autores_tab());
INSERT INTO LIBROS VALUES (2,'Sistemas operativos: fundamentos básicos','Alfaomega',2009,'Informática',autores_tab());
COMMIT;
/
--Insertando autores de libros
INSERT INTO THE(
SELECT L.autor
FROM libros L
WHERE L.id_libro = 1)
VALUES (
autores_type('564212',nombres_type('Amanda','Miller','f'),nacimiento_type('Alemania','Colonia',1978))
);
COMMIT;
>>>>>HERE SHOULD HAVE PROBLEMS BECAUSE THE AGE IS 2012 so is only 5 years old.
INSERT INTO THE(
SELECT L.autor
FROM libros L
WHERE L.id_libro = 1)
VALUES (
autores_type('511111',nombres_type('miuu','dfgg','f'),nacimiento_type('arge','arge',2012))
);
COMMIT;
Autor is table type (not single object):
CREATE OR REPLACE TRIGGER CHEQ_EDAD_AUTOR4
BEFORE INSERT OR UPDATE ON libros
FOR EACH ROW
DECLARE
ANIO_ACTUAL INT := CAST(TO_CHAR(SYSDATE,'YYYY') AS INT);
BEGIN
IF :NEW.autor IS NOT EMPTY THEN
DBMS_OUTPUT.PUT_LINE('año actual' || TO_CHAR(ANIO_ACTUAL) - 'año nacimiento' || TO_CHAR(:NEW.autor(0).nacimiento.anio) );
IF ( ANIO_ACTUAL - :NEW.autor(0).nacimiento.anio ) <18 THEN
RAISE_APPLICATION_ERROR(-20001,'El autor debe ser mayor de 18 años.');
END IF;
END IF;
END;
/
I am trying to show the record after insert it on the table. However my primary key is a substring with a sequence, so I cant find a way to save this value ...this is my code
SET SERVEROUTPUT ON
ACCEPT MARQUE PROMPT "Entrez la marque de la moto "
ACCEPT ANNEE PROMPT "Entrez l annee de la moto: "
ACCEPT PRIX PROMPT "Entrez le prix de la moto: "
DECLARE
myMarque VARCHAR2(50):='&MARQUE';
myAnnee VARCHAR2(6):='&ANNEE';
myPrix NUMBER(6,2):=&PRIX;
lecode VARCHAR2(12);
BEGIN
IF myAnnee = 2013 THEN
INSERT INTO MOTO (CODE, MARQUE, ANNEE, PRIX) VALUES (UPPER(SUBSTR(myMarque, 1,3)||MASEQ.nextval), myMarque, myAnnee, myPrix);
COMMIT;
ELSIF myAnnee = 2014 THEN
INSERT INTO MOTO (CODE, MARQUE, ANNEE, PRIX) VALUES (UPPER(SUBSTR(myMarque, 1,3)||MASEQ.nextval), myMarque, myAnnee, myPrix);
COMMIT;
ELSIF myAnnee = 2015 THEN
INSERT INTO MOTO (CODE, MARQUE, ANNEE, PRIX) VALUES (UPPER(SUBSTR(myMarque, 1,3)||MASEQ.nextval), myMarque, myAnnee, myPrix);
COMMIT;
ELSIF myAnnee = 2016 THEN
INSERT INTO MOTO (CODE, MARQUE, ANNEE, PRIX) VALUES (UPPER(SUBSTR(myMarque, 1,3)||MASEQ.nextval), myMarque, myAnnee, myPrix);
COMMIT;
ELSE
DBMS_OUTPUT.PUT_LINE('Annee invalide SVP VERIFIEZ');
END IF;
END;
/
In short what I need is to show the record after commit , any ideas? I tried to save the value in the variable lecode but it didnt work.
Use the RETURNING clause on your INSERTS, e.g.:
DECLARE
strLast_code MOTO.CODE%TYPE;
BEGIN
INSERT INTO MOTO
(CODE, MARQUE, ANNEE, PRIX)
VALUES
(UPPER(SUBSTR(myMarque, 1,3)||MASEQ.nextval), myMarque, myAnnee, myPrix)
RETURNING CODE INTO strLast_code;
END;
sequence_name.currval will give the current value of sequence.
just like sequence_name.nextval you can get sequence_name.currval
Another solution would be to select directly from the database's metadata:
select last_number from all_sequences where sequence_name='MASEQ';
i don't know how to start !!
i have a work in oracle database,and it is all about triggers and constraints ...
the work is to create triggers and constraints on some tables of database of league of hokey ...
and since i'm new , and not familiar with triggers i have a lot of errs!!!
let's take these two tables as exemple :
1/ "equipe" (means team) table :
Name Null? Type
----------------------------------------- -------- ----------------------------
ID_EQ NOT NULL NUMBER(6)
NOM VARCHAR2(50)
ENREGISTRMENT VARCHAR2(50)
ID_LIG NUMBER(6)
ID_CAPITAINE NUMBER(6)
ID_ENT NUMBER(6)
2/ "joueur" (means player) :
Name Null? Type
----------------------------------------- -------- ----------------------------
ID_JOU NOT NULL NUMBER(6)
NUMERO NUMBER(4)
POSITION VARCHAR2(50)
ID_EQ NUMBER(6)
where :
"id_eq" and "id_jou" are primary keys.
"joueur.id_eq" is referenced to "equipe.id_eq".
"equipe.id_capitaine" is referenced to "joueur.id_jou".
i want to create a trigger that write a msg of err if the user insert in or update the table "equipe" where the "capitaine" is not a player in the team ("equipe") , i try a lot , buttt ... always the msg:
Warning: Trigger created with compilation errors.
This is one of the triggers , if someone can find the err and fix it , or suggest a better one :
CREATE OR REPLACE TRIGGER capitaine_in_equipe
before UPDATE OR INSERT ON equipe
FOR EACH ROW
DECLARE
id_p joueur.id_eq%TYPE;
BEGIN
if (:new.iq_capitaine is not null ) then
SELECT id_eq INTO id_p
FROM joueur
WHERE id_jou = :new.iq_capitaine;
IF ( id_p != :new.id_eq ) THEN
raise_application_error(-20100,' the captain is not a player of the team');
END IF;
END IF;
END;
and if you know some good references of triggers, pl/sql Oracle for biggeners put it, please!
thank you ;)
Surely, there are other way to implement your logic, but if you want to use your trigger, the following works for me
Create equipe:
CREATE TABLE equipe
( ID_EQ number(6) not null,
NOM varchar2(50),
ENREGIS number(6),
ID_CAPITAINE number(6),
ID_ENT number(6),
CONSTRAINT equipe_pk PRIMARY KEY (ID_EQ)
);
Create joueur:
create table joueur
(ID_JOU number(6) not null,
NUMERO number(4),
POSITION varchar2(50),
ID_EQ number(6),
CONSTRAINT joueur_pk PRIMARY KEY (id_jou)
);
Alter both with the foreign key:
alter table equipe add(CONSTRAINT fk_equipe
FOREIGN KEY (ID_CAPITAINE)
REFERENCES joueur(ID_JOU));
alter table joueur add(CONSTRAINT fk_joueur
FOREIGN KEY (id_eq)
REFERENCES equipe(ID_EQ));
Create your trigger:
CREATE OR REPLACE TRIGGER capitaine_in_equipe
before UPDATE OR INSERT ON equipe
FOR EACH ROW
DECLARE
id_p joueur.id_eq%TYPE;
BEGIN
if (:new.id_capitaine is not null ) then
SELECT id_eq INTO id_p
FROM joueur
WHERE id_jou = :new.id_capitaine;
IF ( id_p != :new.id_eq ) THEN
raise_application_error(-20100,' the captain is not a player of the team');
END IF;
END IF;
END;
Notice in your tables definition, you mentioned a column id_capitaine. In your trigger you used the name iq_capitaine. I'm not sure if that reflects your real code or just a typo here.
this is my very first question, I'm new here so I hope I'm asking well in the right topic... etc.
I'm trying with a trigger wich catch information from one table, compares some data from this table and if a condition is true then the trigger have to store the information changing some values. There are my tables and the trigger. I need this trigger to store larger tables with a lot of columns and a lot more information but this is just a test, please help! :'(
create table datos_prueba(
nombre varchar2(10) primary key,
numero number(3),
mensaje varchar(30),
fecha date);
create table store_datos_prueba(
nombre varchar(20) primary key,
numero number(5),
mensaje varchar(30),
fecha date);
And this is the trigger, I worte it but it's wrong...
create or replace trigger tgr_trigger_prueba
after insert on datos_prueba
for each row
declare
cambio_numero number;
begin
if :datos_prueba.numero <= 5 then
insert into store_datos_prueba (nombre,numero,mensaje,fecha) values(:datos_prueba.nombre,666,:datos_prueba.mensaje,:datos_prueba.fecha);
else
insert into store_datos_prueba (nombre,numero,mensaje,fecha) values(:datos_prueba.nombre,777,:datos_prueba.mensaje,:datos_prueba.fecha);
end if;
end;
You have to use old or new to refer the row value. Not the table name.
create or replace trigger tgr_trigger_prueba
after insert on datos_prueba
for each row
declare
cambio_numero number;
begin
if :new.numero <= 5 then
insert into store_datos_prueba (nombre,numero,mensaje,fecha) values(:new.nombre,666,:new.mensaje,:new.fecha);
else
insert into store_datos_prueba (nombre,numero,mensaje,fecha) values(:new.nombre,777,:new.mensaje,:new.fecha);
end if;
end;
/
More on Triggers