Can't create TRIGGER - oracle

I need to create a script to delete some data in a database, the table doesn't have the CASCADE constraint and I don't have the right to edit them.
So I'm trying to create a TRIGGER to simulate a Cascade delete on a table (and I will remove it just after the script get executed).
Here is my trigger:
CREATE TRIGGER delete_workspace_on_delete_result
BEFORE DELETE ON RESULT
FOR EACH ROW
BEGIN
DELETE FROM WORKSPACE WHERE workspace_result_id = :old.id;
END;
/
I don't understand why it's not working, I just follow the Oracle documentation but I have this error:
Error report -
ERROR: syntax error at or near "BEGIN"
Position: 87
I'm not used to Oracle but can't find a way to make this work by my own.

I don't see anything wrong, it works. Though:
won't work on Oracle 11g or lower because trigger name is too long (can be max 30 characters)
will work on 12c and above
consider using create or replace; if it exists and you try to create it again, it'll fail
Demo on 11g:
SQL> CREATE TABLE workspace (workspace_result_id NUMBER);
Table created.
SQL> CREATE TABLE result (id NUMBER);
Table created.
SQL> CREATE TRIGGER delete_workspace_on_delete_result
2 BEFORE DELETE
3 ON RESULT
4 FOR EACH ROW
5 BEGIN
6 DELETE FROM WORKSPACE
7 WHERE workspace_result_id = :old.id;
8 END;
9 /
CREATE TRIGGER delete_workspace_on_delete_result
*
ERROR at line 1:
ORA-00972: identifier is too long
SQL> CREATE TRIGGER delete_workspace_on_del_result
2 BEFORE DELETE
3 ON RESULT
4 FOR EACH ROW
5 BEGIN
6 DELETE FROM WORKSPACE
7 WHERE workspace_result_id = :old.id;
8 END;
9 /
Trigger created.
SQL>

Related

Control order of database logon trigger execution in Oracle

We have two "AFTER LOGON ON DATABASE" triggers, each owned by different DBA-owned schemas and serving different purposes. Trigger A is consistently getting executed prior to trigger B. We need to reverse that and ensure that trigger B fires first.
According to the documentation, we supposedly could use "PRECEDES ..." syntax to control this, but when used with a database trigger it throws ORA-25025: cannot specify PRECEDES clause, so that's a dead-end.
Any ideas how to control which of these AFTER LOGON triggers fires first?
Does anybody know if dbms_ddl.set_trigger_firing_property can do this with some secret property value?
PRECEDES is about editioning triggers. Check out FOLLOWS
SQL> create or replace
2 trigger trg1
3 after logon on scott.schema
4 begin
5 null;
6 end;
7 /
Trigger created.
SQL>
SQL>
SQL> create or replace
2 trigger trg2
3 after logon on scott.schema
4 follows trg1
5 begin
6 null;
7 end;
8 /
Trigger created.
SQL>
or at database level
SQL> create or replace
2 trigger trg1
3 after logon on database
4 begin
5 null;
6 end;
7 /
Trigger created.
SQL>
SQL>
SQL> create or replace
2 trigger trg2
3 after logon on database
4 follows trg1
5 begin
6 null;
7 end;
8 /
Trigger created.

Oracle SQL - Running scripts

I'm trying to create an Oracle SQL script that defines the field and triggers for multiple tables as part of my initialization for the implementation of a new project. A sample of what I'm trying to do is shown here;
ALTER TABLE TBL_SAP_VENDORS
DROP COLUMN UPT_TS;
ALTER TABLE TBL_SAP_VENDORS
ADD (
UPT_TS TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- The automatic update of fields has to be performed using a trigger
-- First we drop the trigger incase it already exists
drop trigger vendors_updt_mark;
-- Then add the trigger deffinition
CREATE TRIGGER vendors_updt_mark
before insert or update
on TBL_SAP_VENDORS
FOR EACH ROW
BEGIN
:new.UPT_TS := SYSTIMESTAMP;
END;
-- INVENTORY
ALTER TABLE TBL_SAP_INVENTORY
DROP COLUMN UPT_TS;
ALTER TABLE TBL_SAP_INVENTORY
ADD (
UPT_TS TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- The automatic update of fields has to be performed using a trigger
-- First we drop the trigger incase it already exists
drop trigger inventory_updt_mark;
-- Then add the trigger deffinition
CREATE TRIGGER inventory_updt_mark
before insert or update
on TBL_SAP_INVENTORY
FOR EACH ROW
BEGIN
:new.UPT_TS := SYSTIMESTAMP;
END;
When I try executing this in the Oracle SQL Developer I get the message :
Table TBL_SAP_VENDORS altered.
Table TBL_SAP_VENDORS altered.
Trigger VENDORS_UPDT_MARK dropped.
Trigger VENDORS_UPDT_MARK compiled
LINE/COL ERROR
--------- -------------------------------------------------------------
6/1 PLS-00103: Encountered the symbol "ALTER"
Errors: check compiler log
When I open up the compile log I see:
Error(5,1): PLS-00103: Encountered the symbol "ALTER"
How do I run these commands, of which I have about 20 to run in a single script?
thanks
You have to end the creation of a trigger (or any PL/SQL object, for that matter), with a slash on its own line.
...
CREATE TRIGGER vendors_updt_mark
before insert or update
on TBL_SAP_VENDORS
FOR EACH ROW
BEGIN
:new.UPT_TS := SYSTIMESTAMP;
END;
/
....

Oracle configuration. "create or replace" function create invalid object

I recently moved my database to a new server (both Oracle 11g).
In the new host, there is a weird behavior, that whenever I run something like:
create or replace test_trigger
before insert or update
on test_table
for each row
begin
select 1 from dual;
end;
/
The trigger created is invalid without any error in log. I tried to recompile, it still invalid.
It only happen with the function "create or replace". If I drop the trigger and re-create again, it would be valid.
My question is, did I config something incorrectly? How can I check it? Thank you.
Code you posted won't compile, not in any Oracle database I know. Why? Wrong syntax.
Here's a demonstration:
SQL> create or replace test_trigger
2 before insert or update
3 on test_table
4 for each row
5 begin
6 select 1 from dual;
create or replace test_trigger
*
ERROR at line 1:
ORA-00922: missing or invalid option
SQL> end;
SP2-0042: unknown command "end" - rest of line ignored.
SQL> /
So, what's wrong with it?
create (or replace) wants to know what you're going to create. "test_trigger"? As far as Oracle is concerned, that could be "mickey_mouse" and the result will be the same. It is the trigger keyword that is missing
SELECT in PL/SQL requires an INTO clause, so that you could store the result into something
in order to be able to do that, you have to declare a variable
Here's code that, actually, compiles:
SQL> create or replace trigger test_trigger --> this
2 before insert or update
3 on test_table
4 for each row
5 declare
6 l_dummy number; --> this
7 begin
8 select 1
9 into l_dummy --> this
10 from dual;
11 end;
12 /
Trigger created.
SQL>
So, it seems that you misinterpret reality.

Oracle command to create a table from another schema, including triggers?

Using this command, I am able to create a table from another schema, but it does not include triggers. Is it possible to create a table from another schema, including triggers?
create table B.tablename unrecoverable as select * from A.tablename where 1 = 0;
First option is to run CREATE script for those objects, if you have a code repository. I suppose you don't.
If you use any GUI tool, things are getting simpler as they contain the SCRIPT tab that enables you to copy code from source and paste it into target user.
If you're on SQLPlus, it means that you should, actually, know what you're supposed to do. Here's a short demo.
SQL> connect hr/hr#xe
Connected.
SQL> create table detail (id number);
Table created.
SQL> create or replace trigger trg_det
2 before insert on detail
3 for each row
4 begin
5 :new.id := 1000;
6 end;
7 /
Trigger created.
SQL>
SQL> -- you'll have to grant privileges on table to another user
SQL> grant all on detail to scott;
Grant succeeded.
Connect as SCOTT and check what we've got:
SQL> connect scott/tiger#xe
Connected.
SQL> -- now, query ALL_SOURCE and you'll get trigger code
SQL> set pagesize 0
SQL> col text format a50
SQL> select text from all_source where name = 'TRG_DET' order by line;
trigger trg_det
before insert on detail
for each row
begin
:new.id := 1000;
end;
6 rows selected.
SQL>
Yet another option is to export & import table, which will get the trigger as well (I've removed parts that aren't relevant, as Oracle database version):
C:\>exp hr/hr#xe tables=detail file=detail.dmp
About to export specified tables via Conventional Path ...
. . exporting table DETAIL 0 rows exported
Export terminated successfully without warnings.
C:\>imp scott/tiger#xe file=detail.dmp full=y
. importing HR's objects into SCOTT
. importing HR's objects into SCOTT
. . importing table "DETAIL" 0 rows imported
Import terminated successfully without warnings.
C:\>
Check what's imported (should be both table and trigger):
SQL> desc detail
Name Null? Type
----------------------------------------- -------- ---------------
ID NUMBER
SQL> select * From detail;
no rows selected
SQL> insert into detail (id) values (-1);
1 row created.
SQL> select * From detail;
ID
----------
1000
SQL>
Cool; even the trigger works.
There might be some other options, but these 4 should be enough to get you started.

Can't create trigger using SQLPlus in Oracle

I'm Learning Oracle and wanted to try creating a trigger. I tried this example form a book in sqlplus.
SQL> CREATE OR REPLACE TRIGGER policy_bull BEFORE insert or update
2 ON emp
3 FOR EACH ROW
4 BEGIN
5 :new.salary := 200;
6 END
7 /
ERROR at line 1:
ORA-04089: cannot create triggers on objects owned by SYS
even though I logged in as SYS using
sqlplus "sys/oracle as sysdba"
You need to type / on a blank line to tell SQLPLUS to run the statement.
Oracle forbids creating triggers on objects owned by SYS.
Did you create the table emp as SYS? You probably want to be a regular user to do that. emp doesn't sound like a system table.
I think a semi-colon is missing after END.
Also mention SYS.emp
SQL> CREATE OR REPLACE TRIGGER policy_bull BEFORE insert or update
2 of SALARY on EMP
3 FOR EACH ROW
4 BEGIN
5 :new.salary := 200;
6 END
7 /
you have to type the column where the "NEW SALARY" is ppl its SALARY so ...or update of SALARY on EMP...

Resources