How to handle compile time exception in pl/sql block? - sql

Actually its a silly quiestion to ask because why would you allow compile time exceptions in your code, But my situation is some what different.
Actually I am writing a pl/sql block in which I am fetching table names at run time and then using that table name in a query in which I have a where clause " where maker ='AUTO_MAST_MAK' ".. Now the problem is that in some table that "maker" column is not available so the block is not getting compiled.
Can any body help me in solving my problem.. or any suggestions " should I change my approach to my problem"

Dynamic PL/SQL can handle compilation errors:
declare
compile_error exception;
pragma exception_init(compile_error, -06550);
begin
execute immediate q'<
begin
does not compile
end;
>';
exception when compile_error then
dbms_output.put_line('PL/SQL Block did not compile.');
end;
/

Why don't you check this column before generating of PLSQL block?
select table_name,column_name,data_type from user_tab_columns
Just check if the table has this column in runtime.

Related

ora-00900 invalid sql statement execute immediate

I am trying to solve a task with a dynamic SQL, but facing an issue ora-00900 invalid sql statement.
execute immediate 'alter table my_table set interval (NUMTOYMINTERVAL(1, ''MONTH''))';
However, it works in the anonymous block treating the statement to be executed as a string.
DECLARE
str VARCHAR2 (250) := 'alter table my_table set interval (NUMTOYMINTERVAL(1, ''MONTH''))';
BEGIN
execute immediate str;
END;
So where is the issue in the first case? It looks like with escape quotes, but can’t catch this.
As the error says, execute immediate is not a SQL statement. There is an execute command in some clients - SQL*Plus, SQL Developer, SQLcl and possibly others - which is a shorthand wrapper around an anonymous block; but from the error you don't seem to be using one of those. If you were you'd get ORA-06550 and PLS-0010: Encounter edthe symbol "alter table..." when expecting...
execute immediate is a PL/SQL statement. So it is only valid within a PL/SQL block.
It has no meaning in plain SQL; the only execute in the SQL reference is referring to directory object privileges.
Your alter table doesn't make much sense anyway, not sure if that's supposed to be an update, but if so it isn't say what to set to that interval value. It isn't obvious why you need it to be dynamic either. Possibly that reason and the actual statement have been lost in simplifying for posting your question.

Creating databases in for loop, injecting iterator of loop to database name

I would like to create four databases in for-loop. However, I got an error. Could you help me to resolve this problem ?
DO $$
BEGIN
FOR counter IN 1..2 LOOP
CREATE DATABASE 'database_name_%', counter;
END LOOP;
END; $$
ERROR: syntax error at or near "'Counter: %'"
LINE 4: CREATE DATABASE 'Counter: %', counter;
From documentation for the CREATE DATABASE command:
CREATE DATABASE cannot be executed inside a transaction block.
And since:
PostgreSQL actually treats every SQL statement as being executed within a transaction. If you do not issue a BEGIN command, then each individual statement has an implicit BEGIN and (if successful) COMMIT wrapped around it. A group of statements surrounded by BEGIN and COMMIT is sometimes called a transaction block
You can't create database in functions. So even if you can handle current problem, you won't be able to execute this function.

PL/SQL Developer 8.0 LOOP IF ELSE THEN SQL Window

I have a .sql file created under the SQL Window of PL/SQL Developer. It is very loooooog, but basically doing the following:
TRUNCATE TABLE table_1
REUSE STORAGE;
COMMIT;
INSERT INTO table_1
Select * from table2
Where ...;
COMMIT;
Before running this script, however, we need to make sure all the sources are readily loaded. So I want to add a logic like below before this script to perform the check:
Do check the timestamp field of table1 and table2
If table1.timestamp is NOT today
If table2.timestamp is today then execute the script listed above
Else do nothing
End If
Else do nothing
End If
(Maybe wait for 60 minutes)
Loop
I can figure out the LOOP in VBA, but I was more hoping for a way to just add this into the exisiting .sql file, or something other ways that doesn't require me to change a lot to the exiting SQL language. I'm not allowed to use any Program Window in PL/SQL Developer, Unfortunately, since I work in Finance department.
Does anyone know if there's a way to work out a case like this??
Thanks for your help!
You can write anonymous PL/SQL block (see oracle documentation for details). For example, it can looks like:
declare -- keyword
/* Here you can declare some variables */
begin -- keyword (starts script)
/* some statements to do */
exception -- keyword to catch exceptions, if you want to do that
/* statements to process errors */
end; -- keyword (end of script)
/ /* you need this symbol to show oracle that script body is ended
and after this symbol you can write another script, that will
be executed automatically after the first one */
If you don't want declare any variables and catch errors, you can omit DECLARE and EXCEPTION sections.

troubleshooting a oracle stored procedure

Suppose I have to write an oracle stored procedure with a huge number of DML operations. I need to design it as if it fails at any point I should be able to find which particular statement caused the error. One way I know is to use an exception with each of the DML statement in the procedure but I think it is not a feasible option. Is there anyway to probably write to a log file which particular statement caused the error and what error just like in Unix scripting we use $? command to determine the status of last executed command?
Here's an approach you use:
declare
vStge VARCHAR2(100);
begin
vStage := 'Start';
--DML 1;
vSTage := 'Next';
--DML 2;
.
.
.
.
vSTage := 'DOne';
exception
when others then
pr_log_error ($$PLSQL_UNIT, vStage ); -- In this sp write to a log table using autonomous txn
raise; -- or not?
end;
A tidier way would be to put each DML in a sub-procedure of its own, and have a "Start" and "End" log to a log table via a call to a stored proc with an autonomous transaction.

Calling a Stored Procedure in Oracle

This should be something fairly simple and straight-forward but for some reason I can't get it to work. I've created my SProc like so:
create or replace procedure zadmit_migrate_data (zadmit_seq_no number)
is
thisPIDM number;
begin
select pidm into thisPIDM
from saturn.zadmit_core_data
where pk_seqno = zadmit_seq_no;
if thisPIDM is not null then
dbms_output.put_line('thisPIDM is NOT null!');
else
dbms_output.put_line('thisPIDM is null!');
end if;
end zadmit_migrate_data;
And now I've trying to call it like this:
call zadmit_migrate_data(4);
And then I get this error:
ORA-06575 Package or function is in an invalid state.
So I tried this:
execute zadmit_core_data(4);
And instead get this error:
ORA-00900 Invalid SQL statement.
It might be less time consuming to point out where I'm going right, but if anyone can tell me where I'm going wrong that would probably be more useful. :)
If you Google for error ORA-06575, you find:
You tried to execute an SQL statement
that referenced a PLSQL function that
is in an invalid state. This happens
when the function is compiled with
errors.
You can resolve this by:
Correct the errors and then re-compile
the function. Then re-execute the SQL
statement.
Once your procedure compiles, you could execute it like:
begin
zadmit_migrate_data(4);
end;
Shouldn't your execute statement be "execute zadmit_migrate_data(4);" ?
At any rate, running this command:
SELECT object_name FROM user_objects WHERE status='INVALID';
will tell you if you procedure is valid or not.
Executing your CREATE or REPLACE ... command, then immediately executing the command
SHOW ERRORS
should tell you what compilation errors were encountered.
Run this
SQL> alter procedure zadmit_migrate_data compile;
SQL> show errors
Given the simplicity of your procedure, it shouldn't be hard to diagnose the resulting error stack.