I am creating a trigger in Oracle and we are stuggling with the syntax.
I have run it through a code checker several times but it keep saying we have an error at "dbms_output.put_line".
When we try to run it, the code says "trigger created with compilation errors"
CREATE TRIGGER date_trigger
BEFORE INSERT ON PrintJob
FOR EACH ROW
BEGIN
IF StartDate > SysDate THEN
BEGIN
dbms_output.put_line ('Please check date');
END;
Trigger can't reference table columns just by naming them - you'll need :old (or :new) pseudorecord qualifiers, such as in this modified example. It is not that DBMS_OUTPUT.PUT_LINE won't work; you wrote it correctly, but should replace it with the RAISE_APPLICATION_ERROR.
SQL> CREATE TABLE printjob (startdate DATE);
Table created.
SQL> CREATE OR REPLACE TRIGGER date_trigger
2 BEFORE INSERT
3 ON PrintJob
4 FOR EACH ROW
5 BEGIN
6 IF :new.StartDate > SYSDATE
7 THEN
8 -- dbms_output.put_line ('Please check date');
9 RAISE_APPLICATION_ERROR (-20000, 'Please check date');
10 END IF;
11 END;
12 /
Trigger created.
SQL> INSERT INTO printjob
2 VALUES (DATE '2018-02-20');
INSERT INTO printjob
*
ERROR at line 1:
ORA-20000: Please check date
ORA-06512: at "SCOTT.DATE_TRIGGER", line 5
ORA-04088: error during execution of trigger 'SCOTT.DATE_TRIGGER'
SQL>
Related
I want to check the null constraint of a column when inserting a record into a table. There, I am trying to insert a null value through a procedure to a column which cannot be null. Here is my procedure.
CREATE OR REPLACE PROCEDURE RecordInsert(s_id IN NUMBER, pid IN NUMBER, pr_id IN NUMBER, quantity NUMBER, rv DATE, exercise_num NUMBER)
IS
null_constraint EXCEPTION;
PRAGMA EXCEPTION_INIT(null_constraint,-1451);
BEGIN
INSERT INTO Supplier_Part_Project_Tab
VALUES(s_id, pid, pr_id_, quantity, rv);
dbms_output.put_line('The row successfully inserted');
COMMIT;
EXCEPTION
WHEN null_constraint THEN
dbms_output.put_line('The column cannot be NULL');
WHEN OTHERS THEN
pkg_Error.prc_Exeception(exercise_num);
END;
This is how I executed the procedure.
BEGIN
RecordInsert( 1002, '', 2001, 80, (TO_DATE('2003/05/03 09:02:44', 'yyyy/mm/dd hh12:mi:ss AM')),8);
COMMIT;
END;
In the above procedure, I am trying to insert pid as null. There, I want to fire the 'null_constraint' exception. But it fires the 'OTHERS' exception. Hope the oracle exception -1451 is correct for my requirement. But why does it not fire?
Sample table:
SQL> CREATE TABLE test
2 (
3 id NUMBER NOT NULL,
4 name VARCHAR2 (20) NOT NULL
5 );
Table created.
Procedure without exception handling section (to see what will happen):
SQL> CREATE OR REPLACE PROCEDURE RecordInsert (par_id IN NUMBER,
2 par_name IN VARCHAR2)
3 IS
4 null_constraint EXCEPTION;
5 PRAGMA EXCEPTION_INIT (null_constraint, -1451);
6 BEGIN
7 INSERT INTO test (id, name)
8 VALUES (par_id, par_name);
9
10 DBMS_OUTPUT.put_line ('The row successfully inserted');
11 /*
12 EXCEPTION
13 WHEN null_constraint
14 THEN
15 DBMS_OUTPUT.put_line ('The column cannot be NULL');
16 WHEN OTHERS
17 THEN
18 DBMS_OUTPUT.put_line ('Others');
19 */
20 END;
21 /
Procedure created.
Testing:
SQL> exec recordinsert(1, 'Littlefoot');
The row successfully inserted
PL/SQL procedure successfully completed.
SQL> exec recordinsert(2, null);
BEGIN recordinsert(2, null); END;
*
ERROR at line 1:
ORA-01400: cannot insert NULL into ("SCOTT"."TEST"."NAME")
ORA-06512: at "SCOTT.RECORDINSERT", line 7
ORA-06512: at line 1
SQL>
Aha. ORA-01400 (not 1451). Let's modify the procedure, then:
SQL> CREATE OR REPLACE PROCEDURE RecordInsert (par_id IN NUMBER,
2 par_name IN VARCHAR2)
3 IS
4 null_constraint EXCEPTION;
5 PRAGMA EXCEPTION_INIT (null_constraint, -1400);
6 BEGIN
7 INSERT INTO test (id, name)
8 VALUES (par_id, par_name);
9
10 DBMS_OUTPUT.put_line ('The row successfully inserted');
11 EXCEPTION
12 WHEN null_constraint
13 THEN
14 DBMS_OUTPUT.put_line ('The column cannot be NULL');
15 WHEN OTHERS
16 THEN
17 DBMS_OUTPUT.put_line ('Others');
18 END;
19 /
Procedure created.
SQL> set serveroutput on
SQL>
SQL> exec recordinsert(2, null);
The column cannot be NULL --> here's your exception
PL/SQL procedure successfully completed.
SQL>
Error code you used was
ORA-01451: column to be modified to NULL cannot be modified to NULL
Cause: The column may already allow NULL values, the NOT NULL constraint is part of a primary key or check constraint, or an ALTER TABLE MODIFY statement attempted to change a column specification unnecessarily, from NULL to NULL.
Action: If a primary key or check constraint is enforcing the NOT NULL constraint, then drop that constraint.
It is related to ALTER TABLE statement, not to inserts which try to insert NULL values into NOT NULL columns, e.g.
SQL> create table test (id number not null, name varchar2(20));
Table created.
SQL> desc test
Name Null? Type
----------------------------------------- -------- ----------------------------
ID NOT NULL NUMBER
NAME VARCHAR2(20)
SQL> alter table test modify name null;
alter table test modify name null
*
ERROR at line 1:
ORA-01451: column to be modified to NULL cannot be modified to NULL
SQL>
I want to create auto incrementing ID in my table which should have substrings and is padded.
In order to do that, i created a sequence, function and a trigger as follows:
create sequence account_number_seq
START WITH 1
INCREMENT BY 1
NOCACHE;
create or replace function reginfo_func
return varchar2
is sub varchar2(20);
begin
select SUBSTR(Account_Type,1,2) || SUBSTR(FirstName,1,3) || RPAD(Account_Number_seq.nextval,10,'0')
INTO sub from registeredinfo;
return sub;
end;
create or replace trigger reginfo_trig
before insert on registeredinfo
for each row
begin
if (:new.account_number is null) then
:new.account_number := reginfo_func;
end if;
end;
When inserting/copying data from a table to this table, i'm experiencing this error:
The account number should be generated automatically.
ORA-04091: table CASESTDY.REGISTEREDINFO is mutating, trigger/function may not see it
ORA-06512: at "CASESTDY.REGINFO_FUNC", line 5
ORA-06512: at "CASESTDY.REGINFO_TRIG", line 3
ORA-04088: error during execution of trigger 'CASESTDY.REGINFO_TRIG'
Thank you in advance.
This is because in your function you are trying to SELECT from the table you are modifying.
You don't actually need the function, just change your trigger to be:
create or replace trigger reginfo_trig
before insert on registeredinfo
for each row
begin
if (:new.account_number is null) then
:new.account_number := SUBSTR(:new.Account_Type,1,2) || SUBSTR(:new.FirstName,1,3) || RPAD(Account_Number_seq.nextval,10,'0');
end if;
end;
I am trying to create table with procedure CREATE_TABLE and then insert the information into the created table with procedure PRINT_INFO but I am getting an exception:
Errors: PROCEDURE PRINT_INFO Line/Col: 4/3 PL/SQL: SQL Statement
ignored Line/Col: 4/15 PL/SQL: ORA-00942: table or view does not exist
Errors: PROCEDURE CREATE_TABLE Line/Col: 5/3 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
And here is my code example:
CREATE OR REPLACE PROCEDURE PRINT_INFO
IS
BEGIN
INSERT INTO TABLE_T (TABLE_ID, MESSAGE) VALUES (1, 'Hello World!');
END PRINT_INFO;
/
CREATE OR REPLACE PROCEDURE CREATE_TABLE
IS
BEGIN
CREATE TABLE TABLE_T(
TABLE_ID NUMBER NOT NULL,
MESSAGE VARCHAR2(25),
PRIMARY KEY(TABLE_ID)
);
PRINT_INFO;
END CREATE_TABLE;
/
EXEC CREATE_TABLE;
Where could be the problem? How can I get rid of an exception?
Both procedures have to use dynamic SQL:
print_info because it inserts into a table which - at compilation time - doesn't exist yet
create_table because it runs DDL and - in order to do that - you need to use dynamic SQL
Therefore:
SQL> CREATE OR REPLACE PROCEDURE PRINT_INFO
2 IS
3 BEGIN
4 execute immediate q'[INSERT INTO TABLE_T (TABLE_ID, MESSAGE) VALUES (1, 'Hello World!')]';
5 END PRINT_INFO;
6 /
Procedure created.
SQL> CREATE OR REPLACE PROCEDURE CREATE_TABLE
2 IS
3 BEGIN
4 execute immediate 'CREATE TABLE TABLE_T(' ||
5 'TABLE_ID NUMBER NOT NULL, ' ||
6 ' MESSAGE VARCHAR2(25), ' ||
7 ' PRIMARY KEY(TABLE_ID) ' ||
8 ')';
9
10 PRINT_INFO;
11 END CREATE_TABLE;
12 /
Procedure created.
SQL> EXEC CREATE_TABLE;
PL/SQL procedure successfully completed.
SQL> SELECT * FROM table_t;
TABLE_ID MESSAGE
---------- -------------------------
1 Hello World!
SQL>
You have to declare a string and assign your ddl to that variable then use
execute immediate your_variable ;
create or replace trigger trg_check_placement
before insert
on lds_placement
for each row
declare
plt_count number;
begin
select count(*) into plt_count from lds_placement where TO_CHAR(sysdate,'HH24:MI:SS');
if plt_count >5 then
raise_application_error(-20000, 'Sorry! you cannot create more than five placement a day');
end if;
end;
Keep getting the error invalid relational operator at line 4.Is this the correct way of solving this or am i completely wrong ?
I am trying to learn pl/sql triggers. I am trying to create a simple trigger by tracking tutorial http://www.tutorialspoint.com/plsql/plsql_triggers.htm but I got below error. I searched on the internet but could not find the solution. Could you help me on this issue?
CREATE OR replace TRIGGER display_salary_changes
BEFORE DELETE OR INSERT OR UPDATE ON ok.customers
FOR EACH ROW
DECLARE
sal_diff NUMBER;
BEGIN
sal_diff := :NEW.salary - :OLD.salary;
END;
/
Trıgger DISPLAY_SALARY_CHANGES created.
SP2-0552: Bind Variable "NEW" is not declared.
PL/SQL procedure successfully completed.
Edit: I am using Sql Developer Version 4.1.1
Works for me (example from your link, but it's basically the same as your post):
SQL> create table demo (id integer, salary number);
Table created.
SQL> create or replace trigger display_salary_changes
2 before delete or insert or update on demo
3 for each row
4 when (new.id > 0)
5 declare
6 sal_diff number;
7 begin
8 sal_diff := :new.salary - :old.salary;
9 dbms_output.put_line('Old salary: ' || :old.salary);
10 dbms_output.put_line('New salary: ' || :new.salary);
11 dbms_output.put_line('Salary difference: ' || sal_diff);
12 end;
13 /
Trigger created.
SQL> show errors
No errors.
SQL> insert into demo (id, salary) values (1, 100);
Old salary:
New salary: 100
Salary difference:
1 row created.
SQL> update demo set salary = salary * 1.1 where id = 1;
Old salary: 100
New salary: 110
Salary difference: 10
1 row updated.
In your example it shows
Trıgger DISPLAY_SALARY_CHANGES created.
which doesn't look like SQL*Plus output. What tool did you use?
After that it gives a SQL*Plus SP2-0552 error about an undefined bind variable, followed by
PL/SQL procedure successfully completed.
What procedure was that? I suspect this is the output from a script with some other step that is failing after the trigger is created.
Is the trigger valid? You can normally right-click and check properties in desktop tools, or at the SQL*Plus prompt enter
show errors trigger display_salary_changes
Try this:
CREATE OR replace TRIGGER test_trg
BEFORE DELETE OR INSERT OR UPDATE ON test
FOR EACH ROW
DECLARE
sal_diff NUMBER;
BEGIN
sal_diff := :new.d - :old.d;
END;
/
Can you please check you column name. I have tried your code below and I got output.
create table test
(
no number(10),
sal number(10)
);
CREATE OR replace TRIGGER test_tr
BEFORE DELETE OR INSERT OR UPDATE ON test
FOR EACH ROW
DECLARE
sal_diff NUMBER;
BEGIN
sal_diff := :NEW.sal - :OLD.sal;
dbms_output.put_line(sal_diff);
END;
/
insert into test values(1,100);
update test set sal=200 where no=1;
Output :
1 rows inserted.
4 rows updated.
100
100
100
100
1 rows inserted.
I think it is missing the "REFERENCING NEW AS NEW OLD AS OLD" sentence:
CREATE TRIGGER [trigger_name]
BEFORE INSERT OR UPDATE ON [table_name]
REFERENCING NEW AS NEW OLD AS OLD
FOR EACH ROW