can any solve what is wrong with this please? - oracle

create table account_type
(
acct_type number(3) primary key,
acct_desc Varchar2(30) not null CHECK (acct_desc IN('savings','salary','current','credit')),
acct_wd_limit number(10)
);
create sequence acct_seq;
CREATE OR REPLACE TRIGGER acct_pk
BEFORE INSERT ON account_type
FOR EACH ROW
WHEN (new.acct_type IS NULL)
BEGIN
SELECT acct_seq.NEXTVAL
INTO :new.acct_type
FROM account_type;
END;
i am getting an error on the line before insert on account_type. no idea why
I also tried doing
CREATE OR REPLACE TRIGGER acct_pk
BEFORE INSERT ON account_type
FOR EACH ROW
WHEN (new.id IS NULL)
BEGIN
SELECT acct_seq.NEXTVAL
INTO :new.id
FROM account_type;
END;
Even doing this is giving me an error
create sequence acct_pk
start with 1
increment by 1
max value 999
min value 1
no cycle;
Thanks

Since the author tagged the question with oracle10g, she can't use sequence_name.nextVal in PL/SQL. Solution:
CREATE OR REPLACE TRIGGER acct_pk
BEFORE INSERT ON account_type
FOR EACH ROW
DECLARE
v_acct_type NUMBER;
BEGIN
IF :new.acct_type IS NULL THEN
SELECT acct_seq.NEXTVAL
INTO v_acct_type
FROM dual;
:new.acct_type := v_acct_type;
END IF;
END;

Related

SQL Developer will not insert data

create or replace PROCEDURE ADD_TO_BLACKLIST(
P_EMPLOYEE_USERNAME IN VARCHAR2,
T_CURSOR OUT SYS_REFCURSOR
)
AS
BEGIN
DECLARE
E_COUNT PLS_INTEGER := 0;
BEGIN
SELECT COUNT(*) INTO E_COUNT FROM EXAMPLE_TABLE
WHERE UPPER(EMPLOYEE_USERNAME) LIKE UPPER(P_EMPLOYEE_USERNAME)||'%';
IF E_COUNT = 0 THEN
INSERT INTO EXAMPLE_TABLE
(employee_number, employee_username)
SELECT EMPLOYEE_NUMBER, EMAIL FROM EXAMPLE_VIEW
WHERE UPPER(EMAIL)=CONCAT(UPPER(P_EMPLOYEE_USERNAME), '#microsoft.com');
ELSE
UPDATE EXAMPLE_TABLE
SET (EMPLOYEE_NUMBER, EMPLOYEE_USERNAME) =
(SELECT EMPLOYEE_NUMBER, EMAIL FROM EXAMPLE_VIEW
WHERE UPPER(EMAIL) = CONCAT(UPPER(P_EMPLOYEE_USERNAME), '#microsoft.com'));
COMMIT;
END IF;
OPEN T_CURSOR For
SELECT * FROM EXAMPLE_VIEW
WHERE EMAIL LIKE CONCAT(UPPER(P_EMPLOYEE_USERNAME), '%');
END;
END ADD_TO_BLACKLIST;
This compiles, but when I try to test it with a valid P_EMPLOYEE_USERNAME (which I've confirmed to be in the EXAMPLE_VIEW), I do not see any data being inserted.
I am new to PLSQL and not sure how to figure out the value of E_COUNT
The Example_Table DDL is
CREATE TABLE "Example_Table"
( "EMPLOYEE_NUMBER" NUMBER NOT NULL ENABLE,
"EMPLOYEE_USERNAME" VARCHAR2(250 BYTE) NOT NULL ENABLE,
"ACCOUNT_STATUS" NUMBER DEFAULT 0,
"ACCOUNT_STATUS_LAST_UPDATE" TIMESTAMP (6) DEFAULT SYSDATE NOT NULL ENABLE,
CONSTRAINT "BOE_SAFEGAURD_PK" PRIMARY KEY ("EMPLOYEE_USERNAME"))
The issue is in below line,you are not converting the case after concatenation.please modify and try below,
WHERE UPPER(EMAIL) = UPPER(CONCAT(UPPER(P_EMPLOYEE_USERNAME), '#microsoft.com'));
EDIT : To prove the theory please find below the details.
I have tested this and it works,
DDL to create the tables:
CREATE TABLE Example_Table
( EMPLOYEE_NUMBER NUMBER NOT NULL ENABLE,
EMPLOYEE_USERNAME VARCHAR2(250 BYTE) NOT NULL ENABLE,
ACCOUNT_STATUS NUMBER DEFAULT 0,
ACCOUNT_STATUS_LAST_UPDATE TIMESTAMP (6) DEFAULT SYSDATE NOT NULL ENABLE,
CONSTRAINT BOE_SAFEGAURD_PK PRIMARY KEY (EMPLOYEE_USERNAME));
CREATE TABLE Example_view
( EMPLOYEE_NUMBER NUMBER NOT NULL ENABLE,
EMAIL VARCHAR2(250 BYTE) NOT NULL ENABLE,
ACCOUNT_STATUS NUMBER DEFAULT 0,
ACCOUNT_STATUS_LAST_UPDATE TIMESTAMP (6) DEFAULT SYSDATE NOT NULL ENABLE
);
DML to populate data to example_view that will be used for the test.
insert into example_view values(1,'Test#microsoft.com',1,sysdate);
Modified the procedure to add UPPER on the rightside of the join for both insert and update conditions and place the commit after end if.A good code should have only one commit and that should be at the end of execution before the exception block of main begin..end block.
create or replace PROCEDURE ADD_TO_BLACKLIST(
P_EMPLOYEE_USERNAME IN VARCHAR2,
T_CURSOR OUT SYS_REFCURSOR
)
AS
BEGIN
DECLARE E_COUNT PLS_INTEGER := 0;
BEGIN
SELECT COUNT(*) INTO E_COUNT FROM EXAMPLE_TABLE WHERE UPPER(EMPLOYEE_USERNAME) LIKE UPPER(P_EMPLOYEE_USERNAME)||'%';
IF E_COUNT = 0 THEN
INSERT INTO EXAMPLE_TABLE
(employee_number, employee_username)
SELECT EMPLOYEE_NUMBER, EMAIL FROM EXAMPLE_VIEW WHERE UPPER(EMAIL)=UPPER(CONCAT(UPPER(P_EMPLOYEE_USERNAME), '#microsoft.com'));
ELSE
UPDATE EXAMPLE_TABLE SET (EMPLOYEE_NUMBER, EMPLOYEE_USERNAME) = (SELECT EMPLOYEE_NUMBER, EMAIL FROM EXAMPLE_VIEW WHERE UPPER(EMAIL)=UPPER(CONCAT(UPPER(P_EMPLOYEE_USERNAME), '#microsoft.com')));
END IF;
COMMIT;
OPEN T_CURSOR For
SELECT * FROM EXAMPLE_VIEW WHERE EMAIL LIKE CONCAT(UPPER(P_EMPLOYEE_USERNAME), '%');
END;
END ADD_TO_BLACKLIST;
In an anonymous block invoked the procedure,
DECLARE
T_CURSOR SYS_REFCURSOR;
BEGIN
ADD_TO_BLACKLIST('test',T_CURSOR);
end;
Ran a query to check if records are inserted,
select * from example_table;
Output is below,
You just need a commit after IF-ELSE condition rather than inside it. I have updated your code along with some other minor updates -
create or replace PROCEDURE ADD_TO_BLACKLIST( P_EMPLOYEE_USERNAME IN VARCHAR2,
T_CURSOR OUT SYS_REFCURSOR
)
AS
E_COUNT PLS_INTEGER := 0;
BEGIN
SELECT COUNT(*)
INTO E_COUNT
FROM EXAMPLE_TABLE
WHERE UPPER(EMPLOYEE_USERNAME) LIKE UPPER(P_EMPLOYEE_USERNAME)||'%';
IF E_COUNT = 0 THEN
INSERT INTO EXAMPLE_TABLE
(employee_number, employee_username)
SELECT EMPLOYEE_NUMBER, EMAIL
FROM EXAMPLE_VIEW
WHERE UPPER(EMAIL) = CONCAT(UPPER(P_EMPLOYEE_USERNAME), '#microsoft.com');
ELSE
UPDATE EXAMPLE_TABLE
SET (EMPLOYEE_NUMBER, EMPLOYEE_USERNAME) = (SELECT EMPLOYEE_NUMBER, EMAIL
FROM EXAMPLE_VIEW
WHERE UPPER(EMAIL)=CONCAT(UPPER(P_EMPLOYEE_USERNAME), '#microsoft.com'));
END IF;
COMMIT;
OPEN T_CURSOR For
SELECT *
FROM EXAMPLE_VIEW
WHERE EMAIL LIKE CONCAT(UPPER(P_EMPLOYEE_USERNAME), '%');
END ADD_TO_BLACKLIST;

Set a column value equal to another column with a trigger in Oracle

I have two columns, Id and Descrizione.
I want to set id = descrizione when a user insert a form. How can i do this with a trigger?
I've tried this but it not works
create or replace TRIGGER RUOLI_ID
BEFORE INSERT ON ruoli
FOR EACH ROW
BEGIN
IF :new.id IS NULL THEN
SET :new.id = Descrizione;
END IF;
END;
Close!
CREATE OR REPLACE TRIGGER ruoli_id
BEFORE INSERT
ON ruoli
FOR EACH ROW
BEGIN
:new.id := NVL (:new.id, :new.descrizione);
END;
You can use the WHEN clause which will execute the trigger only when ID is null, as follows:
CREATE OR REPLACE TRIGGER RUOLI_ID
BEFORE INSERT ON RUOLI
FOR EACH ROW
WHEN (NEW.ID IS NULL)
BEGIN
:NEW.ID := :NEW.DESCRIZIONE;
END;
Cheers!!

Difficulty compiling an AFTER INSERT OR UPDATE trigger

I have an EMPLOYEE table with SALARY field. I'm using Oracle SQL developer. I want to write a trigger so that when someone update salary in EMPLOYEE table, it will update Salary field in EMPLOYEE_SALARIES table as low, medium, high. Here's the second table.
CREATE TABLE Employee_Salaries(
Ssn CHAR(9) NOT NULL,
Salary VARCHAR(10),
Log_Date DATE
);
Here's the trigger and procedure to update the Salary field to low, middle or high.
CREATE OR REPLACE PROCEDURE salaryType(x IN NUMBER, y OUT VARCHAR) IS
BEGIN
IF x >= 60000 THEN y := 'HIGH';
ELSIF (x >= 40000 AND x <= 60000) THEN y := 'MEDIUM';
ELSE y := 'LOW';
END IF;
END salaryType;
/
I get compiler error on this trigger. Please tell me what I did wrong or am I missing something.
CREATE OR REPLACE TRIGGER salary1
AFTER INSERT OR UPDATE ON Employee
FOR EACH ROW
BEGIN
DECLARE
salaryRank VARCHAR(10) := ' ';
salaryType(:new.Salary, salaryRank);
INSERT INTO Employee_Salaries(Ssn, Salary, Log_Date) VALUES (:new.Ssn, salaryRank, SYSDATE);
END;
/
Declaration Part is at wrong place(should be before BEGIN and just after FOR EACH ROW statement of TRIGGER's header), Make it as the following :
CREATE OR REPLACE TRIGGER salary1
AFTER INSERT OR UPDATE ON Employee
FOR EACH ROW
DECLARE
salaryRank VARCHAR(10) := ' ';
BEGIN
salaryType(:new.Salary, salaryRank);
INSERT INTO Employee_Salaries(Ssn, Salary, Log_Date) VALUES (:new.Ssn, salaryRank, SYSDATE);
END;
The keyword BEGIN in the trigger is in the wrong place. It should come after the DEFINE block; that is, after you declare salaryrank and before you invoke the procedure.

ORA-04079: invalid trigger specification --- Error occered

My trigger is :
CREATE OR REPLACE trigger TA_C_WARRANTY_AUDIT_TRG
BEFORE INSERT OR DELETE OR UPDATE ON TA_WARRANTY
FOR EACH ROW`enter code here`
ENABLE
DECLARE
v_user VARCHAR2(30);
v_date VARCHAR2(30);
BEGIN
SELECT user, TO_CHAR(sysdate,'DD/MON/YYYY HH24:MI:SS') INTO v_user,v_date FROM dual;
IF INSERTING THEN
INSERT INTO TA_C_WARRANTY_AUDIT(new_name,old_name,user_name,entry_date,operation)
VALUES (:NEW.LAST_UPDATE_ID, NULL,v_user,v_date,'Insert');
ELSIF DELETING THEN
INSERT INTO TA_C_WARRANTY_AUDIT(new_name,old_name,user_name,entry_date,operation)
VALUES (NULL, :OLD.LAST_UPDATE_ID,v_user,v_date,'Delete');
ELSIF UPDATING THEN
INSERT INTO TA_C_WARRANTY_AUDIT(new_name,old_name,user_name,entry_date,operation)
VALUES (:NEW.LAST_UPDATE_ID, :OLD.LAST_UPDATE_ID,v_user,v_date,'Update');
END IF;
END;
/
Looks my code is okay but I got below error message:
ORA-04079: invalid trigger specification
Any suggession or idea will be highly appreciated.
EDIT:
CREATE TABLE TA_C_WARRANTY_AUDIT
(
new_name VARCHAR2(30),
OLD_name VARCHAR2(30),
user_name VARCHAR2(30),
entry_date VARCHAR2(30),
operation VARCHAR2(30)
);
Try to remove ENABLE from your code

Oracle insert into returning

I'm trying return id after insert:
CREATE SEQUENCE seq_osobne_udaje
INCREMENT BY 1 START WITH 1;
CREATE OR REPLACE TRIGGER trig_osobne_udaje_seq
BEFORE INSERT ON osobne_udaje
FOR EACH ROW
BEGIN
SELECT seq_osobne_udaje.nextval INTO :new.id FROM dual;
END;
/
and then:
var tmp number;
insert into osobne_udaje(name,sur,born,is_man)
values('Jacob','Wulp',to_date('28.07.1992','DD.MM.YYYY'),'Y')
returning id into tmp;
but it write exception in insert row: SQL Error: ORA-00905: missing keyword
This script works in SQL Developer:
DROP TRIGGER trig_osobne_udaje_seq;
DROP SEQUENCE seq_osobne_udaje;
DROP table osobne_udaje;
create table osobne_udaje(
id NUMBER,
name VARCHAR2(20),
sur VARCHAR2(20),
born DATE,
is_man CHAR(1)
)
/
CREATE SEQUENCE seq_osobne_udaje
INCREMENT BY 1 START WITH 1;
/
CREATE OR REPLACE TRIGGER trig_osobne_udaje_seq
BEFORE INSERT ON osobne_udaje
FOR EACH ROW
BEGIN
:new.id := seq_osobne_udaje.nextval;
END;
/
var tmp number;
/
BEGIN
insert into osobne_udaje(name,sur,born,is_man)
values('Jacob','Wulp',to_date('28.07.1992','DD.MM.YYYY'),'Y')
returning id into :tmp;
END;
/
print tmp;

Resources