TRIGGER tU_DEDPARM_OEFix compiled Warning: execution completed with warning - oracle

I am running below create trigger query in Oracle :-
SQL>CREATE OR REPLACE TRIGGER tU_DEDPARM_OEFix
AFTER INSERT OR UPDATE ON DED_PARM FOR EACH ROW
BEGIN
UPDATE DED_PARM SET
DED_PARM.OVRD_DED_AM = COALESCE(i.OVRD_DED_AM,0.00),
DED_PARM.OVRD_DED_PC = COALESCE(i.OVRD_DED_PC,0.00000)
FROM DED_PARM AS d INNER JOIN inserted AS i
ON (i.INTERNAL_EMPL_ID=d.INTERNAL_EMPL_ID AND
i.APPOINTMENT_ID=d.APPOINTMENT_ID AND
i.DEDTYP_CD=d.DEDTYP_CD AND
i.EFFECTIVE_DT=d.EFFECTIVE_DT)
END; /
After execution of the query i faced below error :-
TRIGGER tU_DEDPARM_OEFix compiled Warning: execution completed with
warning.
Then i ran the below query to see the compilation errors
SQL>show error Errors for TRIGGER TU_DEDPARM_OEFIX;
Below are the errors :-
5/3 PL/SQL: ORA-00933: SQL command not properly ended 2/3
PL/SQL: SQL Statement ignored 10/4 PLS-00103: Encountered
the symbol "end-of-file" when expecting one of the following:
( begin case declare end exception 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
Can somebody help me to prepare correct query. FYI- The trigger is created but it is created with compilation errors that i showed above.
Thanks!!

This is not valid syntax for update in Oracle. I'm not sure what inserted do in MSSQL (:new or :old) but I think this is Oracle statement for that trigger
CREATE OR REPLACE TRIGGER tU_DEDPARM_OEFix
AFTER INSERT OR UPDATE ON DED_PARM FOR EACH ROW
BEGIN
update DED_PARM d SET
OVRD_DED_AM = COALESCE(:new.OVRD_DED_AM,0),
OVRD_DED_PC = COALESCE(:new.OVRD_DED_PC,0)
where INTERNAL_EMPL_ID = :new.INTERNAL_EMPL_ID and
APPOINTMENT_ID = :new.APPOINTMENT_ID and
DEDTYP_CD = :new.DEDTYP_CD and
EFFECTIVE_DT = :new.EFFECTIVE_DT;
END;

Related

Creating a Trigger Before Update [duplicate]

i'm trying to run this simple anonymous block on TOAD but i get the following error. Can someone help me?
That's the code:
BEGIN
FOR REC_CONF IN
(
SELECT DISTINCT CONF.SCHEMA, CONF.TABELLA, CONF.CAMPO, CONF.TIPO_CAMPO, CONF.LUNG_CAMPO,
CONF.CAMPO_ACCESSO
FROM EDWH.EDWH_GDPR_CONFIG CONF
WHERE UPPER(FLAG_CANC) = 'Y'
AND UPPER(SCHEMA) = UPPER('EDWH')
ORDER BY CONF.TABELLA, CONF.CAMPO ASC
)
LOOP
DBMS_OUTPUT.PUT_LINE (REC_CONF.TABELLA);
END LOOP;
END;
This should loop into the EDWH.EDWH_GDPR_CONFIG and print out the attribute into the dbms_output.put_line.
This is the error i get:
[Error] Execution (10: 8): ORA-06550: row 10, column 8:
PLS-00103: Encountered the symbol "end-of-file" when expecting one of the following:
( begin case declare exit for goto if loop mod null pragma
raise return select update while with <an identifier>
<identifier between quotes>
<a bind variable> << continue close current delete fetch
lock insert open rollback savepoint set sql execute commit
forall merge pipe purge)
I believe that you ran the script in a wrong manner. It is a PL/SQL script, so run it either by pressing the F9 key, or pushing the "Execute as script" button in TOAD's toolbar.
If cursor was placed somewhere in this code (e.g. on the BEGIN) and you pressed <Ctrl + Enter>, then you'll get
ORA-06550: line 12, column 4:
PLS-00103: Encountered the symbol "end-of-file" 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
So - run it as script.
Try to add '/' after last "END;"
END LOOP;
END;
/
and execute again

Why EXECUTE IMMEDIATE is needed here?

I am a SQL Server user and I have a small project to do using Oracle, so I’m trying to understand some of the particularities of Oracle and I reckon that I need some help to better understand the following situation:
I want to test if a temporary table exists before creating it so I had this code here:
DECLARE
table_count INTEGER;
var_sql VARCHAR2(1000) := 'create GLOBAL TEMPORARY table TEST (
hello varchar(1000) NOT NULL)';
BEGIN
SELECT COUNT(*) INTO table_count FROM all_tables WHERE table_name = 'TEST';
IF table_count = 0 THEN
EXECUTE IMMEDIATE var_sql;
END IF;
END;
It works normally, so after I executed it once, I added an else statement on my IF:
ELSE
insert into test (hello) values ('hi');
Executed it again and a line was added to my test table.
Ok, my code was ready and working, so I dropped the temp table and tried to run the entire statement again, however when I do that I get the following error:
ORA-06550: line 11, column 19:
PL/SQL: ORA-00942: table or view does not exist
ORA-06550: line 11, column 7:
PL/SQL: SQL Statement ignored
06550. 00000 - "line %s, column %s:\n%s"
*Cause: Usually a PL/SQL compilation error.
*Action:
Then I changed my else statement to this and now it works again:
ELSE
EXECUTE IMMEDIATE 'insert into test (hello) values (''hi'')';
My question is why running individually I can simply use the insert instead of the EXECUTE IMMEDIATE and also why my SELECT statement right after BEGIN still works when all the rest appears to need EXECUTE IMMEDIATE to run properly?
The whole PL/SQL block is parsed at compile time, but the text within a dynamic statement isn't evaluated until runtime. (They're close to the same thing for an anonymous block, but still distinct steps).
Your if/else isn't evaluated until runtime either. The compiler doesn't know that the table will always exist by the time you do your insert, it can only check whether or not it exists at the point it parses the whole block.
If the table does already exist then it's OK; the compiler can see it, the block executes, your select gets 1, and you go into the else to do the insert. But if it does not exist then the parsing of the insert correctly fails with ORA-00942 at compile time and nothing in the block is executed.
Since the table creation is dynamic, all references to the table have to be dynamic too - your insert as you've seen, but also if you then query it. Basically it makes your code much harder to read and can hide syntax errors - since the dynamic code isn't parsed until run-time, and it's possible you could have a mistake in a dynamic statement in a branch that isn't hit for a long time.
Global temporary tables should not be created on-the-fly anyway. They are permanent objects with temporary data, specific to each session, and should not be created/dropped as part of your application code. (No schema changes should be made by your application generally; they should be confined to upgrade/maintenance changes and be controlled, to avoid errors, data loss and unexpected side effects; GTTs are no different).
Unlike temporary tables in some other relational databases, when you create a temporary table in an Oracle database, you create a static table definition. The temporary table is a persistent object described in the data dictionary, but appears empty until your session inserts data into the table. You create a temporary table for the database itself, not for every PL/SQL stored procedure.
Create the GTT once and make all your PL/SQL code static. If you want something closer to SQL Server's local temporary tables then look into PL/SQL collections.
PL/SQL: ORA-00942: table or view does not exist
It is compile time error, i.e. when the static SQL is parsed before even the GTT is created.
Let's see the difference between compile time and run time error:
Static SQL:
SQL> DECLARE
2 v number;
3 BEGIN
4 select empno into v from a;
5 end;
6 /
select empno into v from a;
*
ERROR at line 4:
ORA-06550: line 4, column 26:
PL/SQL: ORA-00942: table or view does not exist
ORA-06550: line 4, column 1:
PL/SQL: SQL Statement ignored
Dynamic SQL:
SQL> DECLARE
2 v number;
3 BEGIN
4 execute immediate 'select empno from a' into v;
5 end;
6 /
DECLARE
*
ERROR at line 1:
ORA-00942: table or view does not exist
ORA-06512: at line 4
In the 1st PL/SQL block, there was a semantic check at compile time, and you could see the PL/SQL: ORA-00942: table or view does not exist. In the 2nd PL/SQL block, you do not see the PL/SQL error.
Bottomline,
At compile time it is not known if the table exists, as it is
only created at run time.
In your case, to avoid this behaviour, you need to make the INSERT also dynamic and use EXECUTE IMMEDIATE. In that way, you can escape the compile time error and get the table created dynamically and also do an insert into it dynamically at run time.
Having said that, the basic problem is that you are trying to create GTT on the fly which is not a good idea. You should create it once, and use it the way you want.
I have modified your code a litle bit and it works as far as logic is concerned. But as exp[lained in earlier posts creating GTT on the fly at run time is not at all is a goood idea.
--- Firstly by dropping the table i.e NO TABLE EXISTS in the DB in AVROY
SET serveroutput ON;
DECLARE
table_count INTEGER;
var_sql VARCHAR2(1000) := 'create GLOBAL TEMPORARY table TEST (
hello varchar(1000) NOT NULL)';
BEGIN
EXECUTE IMMEDIATE 'DROP TABLE AVROY.TEST'; --Added the line just to drop the table as per your comments
SELECT COUNT(*)
INTO table_count
FROM all_tables
WHERE table_name = 'TEST'
AND OWNER = 'AVROY';
IF table_count = 0 THEN
EXECUTE IMMEDIATE var_sql;
dbms_output.put_line('table created');
ELSE
INSERT INTO AVROY.test
(hello
) VALUES
('hi'
);
END IF;
END;
--------------------OUTPUT-----------------------------------------------
anonymous block completed
table created
SELECT COUNT(*)
-- INTO table_count
FROM all_tables
WHERE table_name = 'TEST'
AND OWNER = 'AVROY';
COUNT(*)
------
1
--------
-- Second option is without DROPPING TABLE
SET serveroutput ON;
DECLARE
table_count INTEGER;
var_sql VARCHAR2(1000) := 'create GLOBAL TEMPORARY table TEST (
hello varchar(1000) NOT NULL)';
BEGIN
--EXECUTE IMMEDIATE 'DROP TABLE AVROY.TEST';
SELECT COUNT(*)
INTO table_count
FROM all_tables
WHERE table_name = 'TEST'
AND OWNER = 'AVROY';
IF table_count = 0 THEN
EXECUTE IMMEDIATE var_sql;
dbms_output.put_line('table created');
ELSE
INSERT INTO AVROY.test
(hello
) VALUES
('hi'
);
dbms_output.put_line(SQL%ROWCOUNT||' Rows inserted into the table');
END IF;
END;
-------------------------------OUTPUT-------------------------------------
anonymous block completed
1 Rows inserted into the table
---------------------------------------------------------------------------

How do I convert SQL code to PL/SQL for an APEX process

I've got the below code which works perfectly in SQL Developer, but I need to input the code within a process block in APEX and it is only giving me a PL/SQL option. Below is the code which I've written:
BEGIN
truncate table TEMP_UPLOAD;
Merge into INVOICE b
USING (
SELECT CUSTOMER_CLASS,RULE_AGGREGATOR,BA
FROM CUSTOMER_TEMP_UPLOAD
WHERE CUSTOMER_CLASS = 'CUSTOMER88') u
ON (b.BA = u.BA)
WHEN MATCHED THEN UPDATE SET b.CUSTOMER88_DATE_UPDATED = sysdate
WHEN NOT MATCHED THEN
INSERT (b.CUSTOMER_CLASS,b.RULE_AGGREGATOR,b.BA,b.CUSTOMER88_DATE_ADDED)
VALUES (u.CUSTOMER_CLASS,u.RULE_AGGREGATOR,u.BA,sysdate);
UPDATE INVOICE a
SET a.CUSTOMER88_DATE_REMOVED = sysdate
WHERE BA IN
(select b.BA
from INVOICE b
left join CUSTOMER_temp_upload u
on b.BA = u.BA
where u.BA is null and b.CUSTOMER_CLASS = 'CUSTOMER88');
END;
Getting following error
1 error has occurred
•ORA-06550: line 3, column 14: PLS-00103: Encountered the symbol "TABLE" when expecting one of the following: := . ( # % ;
The error message is pointing you to your TRUNCATE TABLE command.
TRUNCATE is a DDL command - don't call it from PL/SQL. Instead, use a DELETE so that your process will be transaction-safe.
(P.S. it is technically possible to run DDL from PL/SQL using EXECUTE IMMEDIATE - but I don't advise it)
Seems that the issue was it did not like my BEGIN and END; in uppercase. When I changed it to Begin and end; as well as changed the TRUNCATE table command to a delete, it then accepted it and the PL/SQL command worked as intended.

Oracle stored procedure

Can anyone help me by telling me what is wrong with the following syntax? I am just trying to run a simple SELECT statement in a stored procedure.
CREATE OR REPLACE PROCEDURE PVSSRDB.GETBATTERYSTATUSFORALLLOGGERS
(
p_Logger OUT e.comment_,
p_tStamp OUT h.ts,
p_Val OUT h.value_number
)
AS
BEGIN
select
e.comment_,
max(h.ts),
avg(h.value_number)
INTO
p_Logger,
p_tStamp,
p_Val
FROM
PVSSRDB.ELEMENTS e inner join PVSSRDB.DB15MINHISTORY_00100009 h on h.element_id =e.element_id
WHERE
e.element_name like 'System1:H%.BatteryCondition'
GROUP BY
e.comment_
ORDER by 2 asc
END GETBATTERYSTATUSFORALLLOGGERS;
I keep getting the same 3 errors stating:
Error(9,3): PL/SQL: SQL Statement Ignored
Error(23,18): PL/SQL: ORA_00933: SQL command not properly ended
Error(24,34): PLS-00103: Encountered the symbol "end-of-file" when expecting one of the following: ( begin case declare end exception 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
You're missing a semicolon after the ORDER BY 2 asc
Also you need to declare your OUT parameters properly.
CREATE OR REPLACE
PROCEDURE PVSSRDB.GETBATTERYSTATUSFORALLLOGGERS (
p_Logger OUT PVSSRDB.ELEMENTS.comment_%TYPE,
p_tStamp OUT PVSSRDB.DB15MINHISTORY_00100009.ts%TYPE,
p_Val OUT PVSSRDB.DB15MINHISTORY_00100009.value_number%TYPE
)
AS
BEGIN
select e.comment_,
max(h.ts),
avg(h.value_number)
INTO p_Logger,
p_tStamp,
p_Val
FROM PVSSRDB.ELEMENTS e
inner join PVSSRDB.DB15MINHISTORY_00100009 h on (h.element_id =e.element_id)
WHERE e.element_name like 'System1:H%.BatteryCondition'
GROUP BY e.comment_
ORDER by 2 asc;
END GETBATTERYSTATUSFORALLLOGGERS;

compile error when creating an "instead of" trigger for a view

I've created an "instead of" trigger for a simple view that only does select * on a table and a trigger that does nothing (I wanted to minimize the problem):
create or replace view tmp(id, nazwa, nip, adres, zalega, punkty) as
select * from klient
create or replace trigger tmp_trg
instead of insert
on tmp
for each row
begin
end;
The view is created.
Then when I want do declare this trigger sql developer returns error:
Error(8,1): PLS-00103: Encountered the symbol "END" when expecting one of the following: begin case declare exit for goto if loop mod null pragma raise return select update while with 'an identifier' 'a double-quoted delimited-identifier' 'a bind variable' << close current delete fetch lock insert open rollback savepoint set sql execute commit forall merge pipe
just add "null;" between the begin and the end.
a trigger that does nothing (I wanted to minimize the problem):
I'm not sure I understand why you need a trigger if it does nothing ?
To answer, there isn't a valid PL/SQL statement in your trigger code block, add a NULL to make it a valid block and have no action.
create or replace trigger tmp_trg
instead of insert
on tmp
for each row
begin
NULL;
end;

Resources