I am in the process of trying to create multiple PL/SQL Scripts to help maintain our existing databases and allow us to make modifications to them. The first one I'm working on is shown below:
BEGIN
-- add the field to the table that will be used to check against when
-- looking for records that need to be processed.
EXECUTE IMMEDIATE('
ALTER TABLE TBL_SAP_VENDORS_COPY
ADD UPT_TS TIMESTAMP ;
');
-- The automatic update of fields has to be performed using a trigger
-- First we drop the trigger incase it already exists
Execute Immediate ('
drop trigger vendors_updt_mark;
');
EXECUTE IMMEDIATE ('
-- Then add the trigger deffinition
CREATE TRIGGER vendors_updt_mark
before insert or update
on TBL_SAP_VENDORS_COPY
FOR EACH ROW
BEGIN
:new.UPT_TS := SYSTIMESTAMP;
END;
');
END;
I'm having problems with the very 1st statement which is the alter statement:
ALTER TABLE TBL_SAP_VENDORS_COPY
ADD UPT_TS TIMESTAMP ;
When I execute it using the 'Run Script' option in Oracle SQL Developer I get the following error:
Error starting at line : 1 in command -
BEGIN
-- add the field to the table that will be used to check against when
-- looking for records that need to be processed.
EXECUTE ('
ALTER TABLE TBL_SAP_VENDORS_COPY
ADD UPT_TS TIMESTAMP ;
');
-- The automatic update of fields has to be performed using a trigger
-- First we drop the trigger incase it already exists
Execute Immediate ('
drop trigger vendors_updt_mark;
');
EXECUTE IMMEDIATE ('
-- Then add the trigger deffinition
CREATE TRIGGER vendors_updt_mark
before insert or update
on TBL_SAP_VENDORS_COPY
FOR EACH ROW
BEGIN
:new.UPT_TS := SYSTIMESTAMP;
END;
');
END;
Error report -
ORA-06550: line 4, column 5:
PLS-00201: identifier 'EXECUTE' must be declared
ORA-06550: line 4, column 5:
PL/SQL: Statement ignored
06550. 00000 - "line %s, column %s:\n%s"
*Cause: Usually a PL/SQL compilation error.
*Action:
Error starting at line : 1 in command -
BEGIN
-- add the field to the table that will be used to check against when
-- looking for records that need to be processed.
EXECUTE IMMEDIATE('
ALTER TABLE TBL_SAP_VENDORS_COPY
ADD UPT_TS TIMESTAMP ;
');
-- The automatic update of fields has to be performed using a trigger
-- First we drop the trigger incase it already exists
Execute Immediate ('
drop trigger vendors_updt_mark;
');
EXECUTE IMMEDIATE ('
-- Then add the trigger deffinition
CREATE TRIGGER vendors_updt_mark
before insert or update
on TBL_SAP_VENDORS_COPY
FOR EACH ROW
BEGIN
:new.UPT_TS := SYSTIMESTAMP;
END;
');
END;
Error report -
ORA-01735: invalid ALTER TABLE option
ORA-06512: at line 4
01735. 00000 - "invalid ALTER TABLE option"
*Cause:
*Action:
When is execute the same statement by itself in SQL Developer is executes with not problem.'
You want:
brackets around the column definition;
to remove the trailing semi-colon in the EXECUTE IMMEDIATE strings when you are executing an SQL command (however, it is required for PL/SQL blocks); and
to catch the exception if the trigger does not exist when you try to drop it.
Like this:
BEGIN
-- add the field to the table that will be used to check against when
-- looking for records that need to be processed.
EXECUTE IMMEDIATE('ALTER TABLE TBL_SAP_VENDORS_COPY ADD ( UPT_TS TIMESTAMP )');
-- The automatic update of fields has to be performed using a trigger
-- First we drop the trigger incase it already exists
DECLARE
trigger_not_found EXCEPTION;
PRAGMA EXCEPTION_INIT( trigger_not_found, -4080 );
BEGIN
Execute Immediate ('drop trigger vendors_updt_mark');
EXCEPTION
WHEN trigger_not_found THEN
NULL;
END;
-- Then add the trigger deffinition
EXECUTE IMMEDIATE ('
CREATE TRIGGER vendors_updt_mark
before insert or update
on TBL_SAP_VENDORS_COPY
FOR EACH ROW
BEGIN
:new.UPT_TS := SYSTIMESTAMP;
END;
');
END;
/
db<>fiddle here
Related
FOR k in c2 LOOP
l_sql := 'ALTER TABLE :TABLE_NAME DISABLE CONSTRAINT
:CONSTRAINT_NAME CASCADE';
l_sql :='INSERT INTO TMP_CONSTRAINT (TABLE_NAME,CONSTRAINT_NAME)
VALUES ('':TABLE_NAME'', '':CONSTRAINT_NAME'')';
EXECUTE IMMEDIATE l_sql USING k.TABLE_NAME, k.CONSTRAINT_NAME;
END LOOP;
Above dynamic SQL to take the variable from a cursor and disable constraint accordingly and insert record to a temp table. I am getting error "bind variable does not exist" in the update statement.
It is actually caused by the single code in INSERT
Corrected as per following:
l_sql :='INSERT INTO TMP_ENABLED_CONSTRAINT (TABLE_NAME,CONSTRAINT_NAME) VALUES (:TABLE_NAME ,:CONSTRAINT_NAME)';
I am trying to implement Trigger that raises an User Defined Error Message and does not allow the update and Insert operation in the database.I am new to pl/sql i refereed some code from the internet and try to implement.My code is running is fine as i can not update/insert into database but still i am unable to get my user defined message and also i am getting this warning.
Warning: Trigger created with compilation errors ?
This is the table :
Name Null? Type
----------------------------------------- -------- ----------------------------
ID NUMBER(5)
NAME VARCHAR2(20)
SALARY NUMBER(10)
DEPOT_ADDRESS VARCHAR2(15)
here is my code :
create or replace trigger cleaner_before_update_insert
for update or insert on cleaner
compound trigger
count binary_integer;
before statement is
begin
count:=0;
end before statement;
after each row is
begin
count :=count +1;
end after each row;
after statement is
begin
if count > 0 then
raise_application_error( -20001,'Update/insert operation can not be completed ');
end if;
end after statement;
end cleaner_before_update;
/
can anyone help me figure out what is the problem here and way to fix it.
thanks in advance.
Even after compilation of the code it is giving me this error.
ORA-06512: at "SYSTEM.CLEANER_BEFORE_UPDATE_INSERT", line 18
ORA-04088: error during execution of trigger
'SYSTEM.CLEANER_BEFORE_UPDATE_INSERT'
There are couple of problems with your TRIGGER block.
The name of the Trigger cleaner_before_update_insert does not match with the cleaner_before_update after the final end statement.
COUNT is an SQL keyword which is not allowed to be used as a variable in PL/SQL.You would receive the error - Error(10,11): PLS-00204: function or pseudo-column 'COUNT' may be used inside a SQL statement only
So, here is the modified code.
CREATE OR REPLACE TRIGGER cleaner_before_update_insert FOR UPDATE OR
INSERT ON cleaner compound TRIGGER
v_count binary_integer;
before STATEMENT
IS
BEGIN
v_count:=0;
END before STATEMENT;
AFTER EACH row
IS
BEGIN
v_count :=v_count +1;
END AFTER EACH row;
AFTER STATEMENT
IS
BEGIN
IF v_count > 0 THEN
raise_application_error( -20001,'Update/insert operation can not be completed ');
END IF;
END AFTER STATEMENT;
END cleaner_before_update_insert;
/
I'm new to PL/SQL. I'm using oracle 11g XE along with sql developer. I'm trying to create to create an after insert trigger as follows
create or replace trigger tr1
after
insert ON
employee
for each row
begin
print :new.emp_id;
end;
The employee table is as follows
create table employee
( emp_id varchar2(5) primary key,
emp_name varchar2(10),
salary number,
company varchar2(10) foreign key references companies(comp_name)
);
When I run the statement I got a 'enter binds' window for the bind variable :new. But I was confused that why do I need to enter the value for :new since it is pseudorecord. Then I entered 'employee' as the values for :new. Now I'm getting the following error.
Error(2,8): PLS-00103: Encountered the symbol "" when expecting one of the following: := . ( # % ; The symbol ":=" was substituted for "" to continue.
Your problem is not in the :new pseudorecord. The error is coming from the usage of print, which is used to print the bind variable used in successful PL/SQL block or used in an EXECUTE command. For example, you can use it this way:
VARIABLE n NUMBER
BEGIN
:n := 1;
END;
/
Then
PRINT n;
But if you want to test the value being inserted, you can use DBMS_OUTPUT.PUT_LINE like this:
create or replace trigger tr1
after
insert ON
employee
for each row
BEGIN
dbms_output.put_line(:new.emp_id);
END;
/
Enable DBMS_OUTPUT window in your SQL Developer, then run
insert into employee values(1, 'empName', 1000, 'ABC');
You'll see 1 printed out.
However, you can always test the value from the table. Because the value should be already inserted into table. You can just query.
I am trying to insert data in a temp table(my_temp_table) using View(VWBLKDATA) as follows but getting compilation error "Error(7,15): PL/SQL: ORA-00942: table or view does not exist". However i am able to successfully execute view separately.
create or replace PROCEDURE InsrtInTemp
AS
BEGIN
INSERT INTO my_temp_table SELECT * FROM VWBLKDATA;
COMMIT;
END InsrtInTemp;
But when i am writing dynamic query as below, it compiles successfully
create or replace PROCEDURE InsrtInTemp
AS
intrtmp VARCHAR2(200);
BEGIN
intrtmp := 'INSERT INTO my_temp_table SELECT * FROM VWBLKDATA';
EXECUTE IMMEDIATE intrtmp;
END InsrtInTemp;
Please help me understanding this behavior.
I am trying to create database by my java application using my generated schema file. In schema I have included drop query also. But I want to do some improvements for DROP QUERY. So I want to check the existence of db objects before running drop query and drop only when if it exists.
I googled for it and found some oracle link, Some link suggest following syntax and some mentioned that ORACLE does not support such syntax.
SYNTAX A:
IF EXISTS DROP TABLE TABLE_NAME
SYNTAX B:
DROP [TEMPORARY] TABLE [IF EXISTS]
tbl_name [, tbl_name] ...
[RESTRICT | CASCADE]
I also tried following queries:-
IF EXISTS (SELECT * FROM dba_objects WHERE OBJECT_NAME = 'BBB' )
DROP TABLE [BBB]
but it was giving error:-
Error starting at line 2 in command:
DROP TABLE [BBB]
Go
Error report:
SQL Error: ORA-00903: invalid table name
00903. 00000 - "invalid table name"
*Cause:
*Action:
Error starting at line 1 in command:
IF EXISTS (SELECT * FROM dba_objects WHERE OBJECT_NAME = 'BBB' ) DROP TABLE [BBB]
Error report:
Unknown Command
I refered following links:-
https://community.oracle.com/thread/2421779?tstart=0
Please suggest me if there any other queries to drop table with condition if table exists.
Drop table with no check. If any error exists you'll never know when something went wrong.
BEGIN
EXECUTE IMMEDIATE 'DROP TABLE my_table';
EXCEPTION
WHEN OTHERS THEN
NULL;
END;
Or you can search in Oracle dictionary.
DECLARE
l_cnt NUMBER;
BEGIN
SELECT count(*)
INTO l_cnt
FROM user_tables
WHERE table_name = 'MY_TABLE';
IF l_cnt = 1 THEN
EXECUTE IMMEDIATE 'DROP TABLE my_table';
END IF;
END;
If you run following code you do not have to check if table exists and in case of errors (table is locked with now wait or any other you will know about it)
begin
for c1 in (select owner,table_name from dba_tables where table_name='MY_TABLE') loop
execute immediate 'drop table '||c1.owner||'.'||c1.table_name||'';
end loop;
end;
Try this : It will drop table 'table_name' if it is present .
declare
a varchar2(700) ;
begin
execute immediate ' SELECT CASE WHEN tab = 1
THEN ''DROP TABLE TABLE_NAME''
ELSE ''select 1 from dual''
END
FROM ( SELECT sum(case when table_name = ''TABLE_NAME'' then 1 else 0 end ) as tab FROM user_tables)' into a;
EXECUTE IMMEDIATE a;
end;