SQLite trigger error : rollback - sql

I get the following error when I try to create this trigger in SQLite
create trigger timeslot_check1 after insert on section
for each row
when(new.time_slot_id not in(select time_slot_id
from time_slot))
begin
rollback
end;
ERROR : near "rollback": syntax error:

As shown in the documentation, the only SQL commands allowed in a trigger body are UPDATE, INSERT, DELETE, and SELECT.
To raise an error, you must use the RAISE() function from inside a query:
CREATE TRIGGER timeslot_check1
BEFORE INSERT ON section
FOR EACH ROW
WHEN NEW.time_slot_id NOT IN (SELECT time_slot_id FROM time_slot)
BEGIN
SELECT RAISE(FAIL, "invalid timeslot");
END;
Anyway, this check can be done much easier with a foreign key.

Related

Why am I getting this error? PLS-00103: Encountered the symbol "CREATE" when expecting one of the following:

I am getting this error
Compilation failed, line 2 (11:52:47) The line numbers associated with compilation errors are relative to the first BEGIN statement. This only affects the compilation of database triggers.
PLS-00103: Encountered the symbol "CREATE" when expecting one of the
following: ( begin case declare exit for goto if loop mod null pragma
raise return select update while with << continue close current
delete fetch lock insert open rollback savepoint set sql execute
commit forall merge pipe purge json_exists json_value json_query
json_object json_array
Code:
create or replace trigger "GDS_CLIENT_T1"
BEFORE
insert or update or delete on GDS_CLIENT
for each row
begin
create or replace trigger "client insert"
before
insert on "Identify Client"
for each row
begin
select nv1(max(id),0)+1 into :NEW_ID FROM IDENTIFY CLIENT
end;
CREATE OR REPLACE TRIGGER is a DDL command that requires a full specification of the trigger to create; in your case, your first command has not ended:
create or replace trigger "GDS_CLIENT_T1"
BEFORE
insert or update or delete on GDS_CLIENT
for each row
begin
At this point it is expected that you will finish the definition of the GDS_CLIENT_T1 trigger; but instead, you have create or replace trigger which is not valid PL/SQL.

Why inside of a trigger the code before raise_application_error isn't executed?

IF I create this trigger, then the error is raised when drop or truncate is used on tables, but there is nothing inserted into logTable, but if I delete RAISE_APPLICATION_ERROR... then the values are inserted into logTable, but the drop/truncate are executed too. Why? How can I avoid drop/truncate on Schema (If I use instead of trigger, it is fired only if owner of the schema is dropping/truncating something).
CREATE OR REPLACE TRIGGER trigger_name
BEFORE DROP OR TRUNCATE ON DATABASE
DECLARE
username varchar2(100);
BEGIN
IF ora_dict_obj_owner = 'MySchema' THEN
select user INTO username from dual;
INSERT INTO logTable VALUES(username , SYSDATE);
RAISE_APPLICATION_ERROR (-20001,'ERROR, YOU CAN NOT DELETE THIS!!');
END IF;
END;
According to the documentation:
Statement-Level Atomicity
Oracle Database supports statement-level atomicity, which means that a SQL statement is an atomic unit of work
and either completely succeeds or completely fails.
A successful statement is different from a committed transaction. A
single SQL statement executes successfully if the database parses and
runs it without error as an atomic unit, as when all rows are changed
in a multirow update.
If a SQL statement causes an error during execution, then it is not
successful and so all effects of the statement are rolled back. This
operation is a statement-level rollback.
The procedure is a PL/SQL statement, it is atomic, if you raise an error within the procedure, then the whole procedure fails and Oracle performs a rollback of all the changes done by this procedure.
But you can create a procedure with AUTONOMOUS_TRANSACTION Pragma in order to bypass this behaviour, in this way:
CREATE TABLE logtable(
username varchar2(200),
log_date date
);
CREATE OR REPLACE PROCEDURE log_message( username varchar2 ) IS
PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
INSERT INTO logtable( username, log_date ) VALUES ( username, sysdate );
COMMIT;
END;
/
CREATE OR REPLACE TRIGGER trigger_name
BEFORE DROP OR TRUNCATE ON DATABASE
DECLARE
username varchar2(100);
BEGIN
IF ora_dict_obj_owner = 'TEST' THEN
log_message( user );
RAISE_APPLICATION_ERROR (-20001,'ERROR, YOU CAN NOT DELETE THIS!!');
END IF;
END;
And now:
drop table table1;
ORA-00604: error occurred at recursive SQL level 1
ORA-20001: ERROR, YOU CAN NOT DELETE THIS!!
ORA-06512: at line 6
00604. 00000 - "error occurred at recursive SQL level %s"
*Cause: An error occurred while processing a recursive SQL statement
(a statement applying to internal dictionary tables).
*Action: If the situation described in the next error on the stack
can be corrected, do so; otherwise contact Oracle Support.
select * from logtable;
USERNAME LOG_DATE
-------- -------------------
TEST 2018-04-27 00:16:34

oracle sql developer missing on keyword

I keep getting the "missing on keyword" message on the following query and I'm not sure why:
CREATE OR REPLACE TRIGGER TRG_LINE_PRODUCT AFTER INSERT UPDATE OR DELETE ON
TBL_CH08_LINE FOR EACH ROW
BEGIN
IF INSERTING THEN UPDATE TBL_CH08_PRODUCT P SET P_QOH = P_QOH-:NEW.LINE.UNITS
WHERE P.P_CODE = :NEW.P.P_CODE;
END IF;
END;
/
You are missing an OR, in fact:
CREATE OR REPLACE TRIGGER TRG_LINE_PRODUCT
AFTER INSERT OR UPDATE OR DELETE ON TBL_CH08_LINE
-----------------^
FOR EACH ROW
Oracle is expecting ON after the INSERT, which is why you get that particular error.

Oracle SQL trigger - DBMS_OUTPUT.PUT_LINE

I'm creating a trigger within my database, I came across two error that I am not able to fix, I'm pretty sure that those two are relating to my use of DBMS_OUTPUT.PUT_LINE, the rest of the statement does not cause any errors, although it had before.
Errors:
Error(5,3): PL/SQL: SQL Statement ignored
Error(5,15): PL/SQL: ORA-00903: invalid table name
Code:
CREATE TRIGGER INVOICES
BEFORE INSERT OR UPDATE ON BRUINVOICE
FOR EACH ROW
BEGIN
IF :new.BRU_DATE < :new.BRU_PAID_DATE THEN
DBMS_OUTPUT.PUT_LINE('You cannot do that');
ELSE
INSERT INTO table BRUINVOICE
values
from inserted;
END IF;
END;
Check constraints are a better choice (performance-wise) than triggers when it comes to record level validation:
ALTER TABLE bruinvoice
ADD CONSTRAINT validate_bru_date CHECK (BRU_DATE < BRU_PAID_DATE);
Inserting invalid data will raise an error message like the following:
scott#ORCL> insert into bruinvoice values ('21-DEC-14','20-DEC-14');
insert into bruinvoice values ('21-DEC-14','20-DEC-14')
*
ERROR at line 1:
ORA-02290: check constraint (SCOTT.VALIDATE_BRU_DATE) violated
I fully agree with cstotzer, a check constraint is much better in your situation at should be the preferred way of doing it. However, just for information this would be the trigger syntax:
CREATE TRIGGER INVOICES
BEFORE INSERT OR UPDATE ON BRUINVOICE
FOR EACH ROW
BEGIN
IF :new.BRU_DATE < :new.BRU_PAID_DATE THEN
RAISE_APPLICATION_ERROR(-20001, 'You cannot do that');
END IF;
END;
You don't need any ELSE, your INSERT or UPDATE will be simply executed in this case.

Error: ORA-00969: missing ON keyword - Oracle

I am using Oracle 11g XE database and Oracle SQL developer to execute SQL statements.
I have this SQL statement which is giving me the above compiler error when executing it.
CREATE OR REPLACE
TRIGGER "STD"."TRG_STUDENT"
BEFORE INSERT,DELETE
ON STUDENT
FOR EACH ROW
BEGIN
IF INSERTING THEN
DBMS_OUTPUT.PUT_LINE('Inserting !!');
END IF;
IF DELETING THEN
DBMS_OUTPUT.PUT_LINE('Deleting !!');
END IF;
END;
I tried some variations but I used to get other errors.
I placed the ON STUDENT just before the BEFORE INSERT,DELETE line and I get this error:
Error: ORA-04071: missing BEFORE, AFTER or INSTEAD OF keyword
What am I missing here?
BEFORE INSERT OR DELETE
More about Create Trigger syntax: http://docs.oracle.com/cd/B19306_01/server.102/b14200/statements_7004.htm
Use BEFORE INSERT OR DELETE instead of BEFORE INSERT, DELETE. Refer coding trigger for more in detail.