Error pls-00403 oracle - sql

CREATE OR REPLACE TRIGGER TR_BCK_ANAG
BEFORE DELETE OR INSERT OR UPDATE ON ANAGRAFICA
FOR EACH ROW
BEGIN
SELECT ID ,
NOME ,
COGNOME ,
DATA ,
NUMERO_DI_TELEFONO ,
COMUNE
INTO BCK_ANAG
FROM ANAGRAFICA;
END;
Why does oracle give me back error
PLS-00403:expression 'BCK_ANAG' cannot be used as an INTO-target of a
SELECT/FETCH statement
and how can i solve this?

CREATE OR REPLACE TRIGGER TR_BCK_ANAG
BEFORE DELETE OR INSERT OR UPDATE
ON ANAGRAFICA
FOR EACH ROW
BEGIN
INSERT INTO BCK_ANAG (ID,
NOME,
COGNOME,
DATA,
NUMERO_DI_TELEFONO,
COMUNE)
SELECT :NEW.ID,
:NEW.NOME,
:NEW.COGNOME,
:NEW.DATA,
:NEW.NUMERO_DI_TELEFONO,
:NEW.COMUNE
FROM DUAL;
END;
I would assume this is what you're trying to do.

Related

How can I migrate this SQL Server trigger from T-SQL to PL/SQL

The following works on SQL Server but I could not translate it to PL/SQL
PL/SQL:
create or replace TRIGGER CHANGE_TRIGGER
AFTER INSERT OR UPDATE OR DELETE
ON test
FOR EACH ROW
BEGIN
IF INSERTING THEN
INSERT INTO test_LOG
SELECT :NEW.* , SYSDATE, USER, 'I' FROM DUAL;
END IF;
END;
Original SQL Server trigger:
CREATE TRIGGER [dbo].[TRG_LOG_TEST] ON [dbo].[TEST]
FOR INSERT, UPDATE, DELETE
AS
DECLARE #lg_name VARCHAR(128)
SELECT
#lg_name = login_name,
FROM sys.dm_exec_sessions
WHERE session_id = ##SPID
IF EXISTS (SELECT * FROM inserted)
BEGIN
INSERT INTO [TEST_LOG]
SELECT *, GETDATE(), #lg_name ,'I' from deleted
END

How to execute SQL query stored in a table

I have a table having one of the columns that stores SQL query.
create table test1
(
name varchar(20),
stmt varchar(500)
);
insert into test1 (name, stmt)
values ('first', 'select id from data where id = 1;')
Data table is like:
create table data
(
id number,
subject varchar(500)
);
insert into data (id, subject) values (1, 'test subject1');
insert into data (id, subject) values (2, 'test subject2');
insert into data (id, subject) values (3, 'test subject2');
Now every time on insert in test1, I need to execute the query that gets inserted in stmt column of test1 and insert queried data to result table:
create table result
(
id number,
subject varchar(500)
);
For that I am writing a trigger that gets executed on every insert in test1 like as follows:
create or replace TRIGGER "TEST_AFTER_INSERT"
BEFORE INSERT or UPDATE ON test1
FOR EACH ROW
DECLARE
sql_stmt VARCHAR2(500);
BEGIN
select stmt into sql_stmt from data where name = :NEW.name;
insert into result(id, subject)
select id,subject from data where id in ('stmt');
END;
Could you please let me know how to achieve this, above trigger is throwing error that I am not able to understand.
You can use a dynamic query in your trigger as follows:
CREATE OR REPLACE TRIGGER "TEST_AFTER_INSERT" AFTER -- CHANGED IT TO AFTER AS NAME SUGGESTS
INSERT OR UPDATE ON TEST1
FOR EACH ROW -- REMOVED DECLARE SECTION
BEGIN
EXECUTE IMMEDIATE 'INSERT INTO result
SELECT ID, SUBJECT FROM DATA WHERE ID IN ('
|| RTRIM(:NEW.STMT, ';')
|| ')';
-- SINGLE QUERY TO INSERT THE DATA
-- USED RTRIM AS STMT HAS ; AT THE END
END;
Cheers!!
Consider direct insertion :
CREATE OR REPLACE TRIGGER "TEST_AFTER_INSERT"
BEFORE INSERT or UPDATE ON test1
FOR EACH ROW
DECLARE
BEGIN
insert into result(id, subject)
select id, subject from data where name = :NEW.name;
END;

SQL Trigger After Update Insert data into another table

I have two table. One is customer_info and another one is update_log. I want to create a trigger that will execute after update in customer_info. If cust_name, Contact is updated then cust_no, Cust_name, Contact, Date will be added to second table. Second table will have two row with old data and new data. my code is not working. Any help will be highly appreciated.
CREATE TRIGGER update_trigger
AFTER UPDATE ON CUSTOMER_info
FOR EACH ROW
BEGIN
IF NEW.cust_name <> OLD.cust_name || NEW.contact <> OLD.contact then
insert into update_log values
( OLD.cust_no,OLD.cust_name, OLD.contact, CURRENT_DATE);
insert into update_log values
( NEW.cust_no,NEW.cust_name, NEW.contact,CURRENT_DATE);
END IF
END
If You use MSSQL, You can use that trigger:
CREATE TRIGGER update_trigger
ON CUSTOMER_info
FOR update AS
BEGIN
IF UPDATE (cust_name) OR UPDATE (contact)
BEGIN
INSERT INTO update_log (
cust_no
,Cust_name
,Contact
,Date
)
SELECT cust_no
,cust_name
,contact
,GetDate()
FROM INSERTED
INSERT INTO update_log (
cust_no
,Cust_name
,Contact
,Date
)
SELECT cust_no
,cust_name
,contact
,GetDate()
FROM DELETED
END
END
GO

Create Insert Trigger PL/SQL

I have write a PL/SQL insert trigger but it doesn't compile properly but I don't see the problem.
create or replace TRIGGER trg_NEWROW
BEFORE INSERT or UPDATE OF STATUS_ID ON application FOR EACH ROW
BEGIN
INSERT INTO APPLICATION_HISTORY
(APPLICATION_ID, STATUS_ID, DATE_OF_CHANGE)
VALUES
(1, 1, SYSDATE)
END;
Try this: You missed a ';' at the end of Insert statement
CREATE OR REPLACE TRIGGER TRG_NEWROW
BEFORE INSERT OR UPDATE OF STATUS_ID
ON APPLICATION
FOR EACH ROW
BEGIN
INSERT INTO
APPLICATION_HISTORY ( APPLICATION_ID,
STATUS_ID,
DATE_OF_CHANGE )
VALUES
( 1,
1,
SYSDATE );
END;
/

Insert/Update in PL/SQL

I have made a procedure in PL/SQL which inserts data from one table to another on basis of primary key. My procedure is working fine but i can't figure out how will i update column CODE_NUMBER of my table MAIN if primary key already exists.
Actually i want rows of MAIN table to get UPDATED when its has primary key and insert data from REGIONS when primary key does not exists.
DECLARE
variable number;
id number;
description varchar2 (100);
CURSOR C1 IS
select regions.REGION_ID variable
from regions;
BEGIN
FOR R_C1 IN C1 LOOP
BEGIN
select regions.REGION_ID,regions.REGION_NAME
into id,description
from regions
where regions.REGION_ID = R_C1.variable;
----If exists then update otherwise insert
INSERT INTO MAIN( ID, CODE_NUMBER) VALUES( id,description);
dbms_output.put_line( id ||' '|| 'Already Exists');
EXCEPTION
WHEN DUP_VAL_ON_INDEX THEN
dbms_output.put_line( R_C1.variable);
END;
END LOOP;
END;
There's no need to do this with PL/SQL and cursors. What you really want to do is something like this:
MERGE INTO MAIN dst
USING (
SELECT regions.REGION_ID id,
regions.REGION_NAME description
FROM regions
) src
ON src.id = dst.id
WHEN MATCHED THEN UPDATE
SET dst.code_number = src.description
WHEN NOT MATCHED THEN INSERT (id, code_number)
VALUES (src.id, src.description)
Read more about the SQL MERGE statement in the documentation
I can not really see a point in doing a cursor in this case. Why can't you just do it like this:
--Update the rows
UPDATE MAIN
SET ID=regions.REGION_ID,
CODE_NUMBER=regions.[description]
FROM MAIN
JOIN regions
ON MAIN.ID=regions.REGION_ID;
--Insert the new ones
INSERT INTO MAIN(ID,CODE_NUMBER)
SELECT
regions.REGION_ID,
regions.[description]
FROM
regions
WHERE NOT EXISTS
(
SELECT
NULL
FROM
MAIN.ID=regions.REGION_ID
)