I've been trying to get SQL Developer to run a query automatically on a regular basis (on the sample HR database). Based on my research, I've determined that the best alternative for me would be to use the Job Wizard & PL/SQL (where it calls DBMS_SCHEDULER?).
I created a 'Schedule' that repeats every 5 minutes called: every_5mins
Here is what I have in the 'Job Details' section thus far:
Job Name: Select_Employees
Job Class: SYS.DEFAULT_JOB_CLASS
Type of Job: PL/SQL block
When to Execute Job: Schedule
Schedule: SYSTEM.EVERY_5MINS
PL/SQL
CREATE OR REPLACE
PROCEDURE get_emp_rs (p_deptno IN HR.FIRST_NAME,
p_recordset OUT SYS_REFCURSOR) AS
BEGIN
OPEN p_recordset FOR
SELECT FIRST_NAME,
LAST_NAME
FROM
HR.EMPLOYEES
WHERE FIRST_NAME=p_recordset
END;
/
it returns an error:
"Encountered the symbol "/" when expecting one of the following: (begin case declare)..." and the rest is cut off the screen
Am I on the right track? What is the proper way to write it so the query is run every 5 mins? I have never used Oracle SQL Developer before.
Thanks in advance.
I have a new error: line 1, column 750 PLS-00103: Encountered the symbol "CREATE"
The PL/SQL payload is the code we want our job to execute. So it seems you are trying to schedule the creation of stored procedure every five minutes. The scheduler is expecting an executable PL/SQL call, not DDL.
So what you need to to is create the stored procedure first, then fire up the Job wizard. The PL/SQL block should be something like this:
declare
rc sys_refcursor;
begin
get_emp_rs ('MAYZIE', rc);
end;
This points us to the underlying problem with your scenario: jobs run in the background. There's no way for a job to accept user input or display output. So while your job will run every five minutes you'll never see the result set. You need a procedure which writes results somewhere (a table, a file) which can be read and displayed by some other program.
Related
I would like to measure the execution time of a stored procedure in Oracle. I have learned about the technique of writing an entry in a temporary logging table at the start and the end but am unable to use this technique.
Can you refer me to an open source/free tool with which I'm able to do this?
Thanks!
The answer depends on your environment you are using.
If you are using SQLPlus, you can enable a timer as follows :t
SQL> set timing on
Then, just execute your procedure, like :
SQL> exec my_procedure;
When the procedure will complete, a summary line will be displayed, like :
PL/SQL procedure successfully completed.
Elapsed: 00:00:03.05
From within PL/SQL, you can use dbms_utility.get_time :
DECLARE
start_time pls_integer;
BEGIN
start_time := dbms_utility.get_time;
exec my_procedure;
dbms_output.put_line((dbms_utility.get_time - start_time)/100 || ' seconds');
END;
/
Should output something like :
3 seconds
PL/SQL procedure successfully completed.
See this excellent explanation from Tom Kyte.
Execution of the stored procedure's start /end time can be logged using
DBMS_UTILITY.get_cpu_time or DBMS_UTILITY.get_time
E.g.
CREATE OR REPLACE PROCEDURE test_proc IS
BEGIN
DBMS_OUTPUT.put_line('start time '||DBMS_UTILITY.get_time);
<your statement>
DBMS_OUTPUT.put_line('end time '||DBMS_UTILITY.get_time);
END;
There are of course other ways of finding the execution time using Profiler
Have a look at this as well
If you want to get details that can actually help you diagnose issues, I highly recommend dbms_profiler.
It is easy to use and provides statistics for every line in the pl/sql including number of executions, total time, min and max.
I am new to plsql and trying to use oracle sql developer, I try to run a simple procedure with dbms output line and i get the following error,
ora-00904
, the code is
create or replace PROCEDURE proc_101 IS
v_string_tx VARCHAR2(256) := 'Hello World';
BEGIN
dbms_output.put_line(v_string_tx);
END;
whether i click the run(green colour) or debug(red colour) i get the same error.
You can see from the above code, procedure doesn't access any objects but still i get the same error.
Your procedure is fine. You may not have permissions to be able to Create a Procedure. If this is the case test your procedure/code without actually Creating it in the Database first. For example, when I'm testing code in my Production database my oracle user cannot Create Procedures, Packages, Tables etc... And so I test my Procedures within my Own PL/SQL Blocks. When the code is good to go I can get a database administrator to Create the Procedures and/or Packages for me.
The below screenshot is code that simply tests the Procedure:
The below screenshot is code that does much more and tests the Procedure from within a PL/SQL Block
For more advanced situations this allows you to do so much more as you can create all sorts of Procedures/Functions and/or Cursors and test them immediately without needing to CREATE these objects in your Oracle Database.
I'd say that there's some other code in the worksheet which raises that error, not just the CREATE PROCEDURE you posted. For example, something like this SQL*Plus example (just to show what's going on - you'd get the same result in SQL Developer):
SQL> select pixie from dual;
select pixie from dual
*
ERROR at line 1:
ORA-00904: "PIXIE": invalid identifier
SQL>
SQL> create or replace PROCEDURE proc_101 IS
2 v_string_tx VARCHAR2(256) := 'Hello World';
3 BEGIN
4 dbms_output.put_line(v_string_tx);
5 END;
6 /
Procedure created.
SQL>
See? The first part raised ORA-00904 as there's no PIXIE column in DUAL, while the procedure is created correctly.
So - remove code which fails and everything should be OK.
Check with your DBA to make sure the dbms_output package has been installed on your database, and that you have permissions on it.
I have a scenario, in which i have one stored proc which contains set of sql statements( combination of joins and sub queries as well, query is large to displays)
and finally result is storing in temp table.
this is executing by user from frontend or programmer from backend with specific permissions.
here the problem is, there is difference in execution time for this query.
sometimes it is taking 10 mins, sometimes it is taking 1 hour, but an average elapsed time is 10 mins, and one common thing is always it is giving the same amount of records (approximately same).
As ErikL mentioned checking the execution plan of the query is a good start. In Oracle 11g you can use the DBMS_PROFILER. This will give you information about the offending statements. I would run it multiple times and see what the difference is between multiple run times. First check to see if you have the DBMS_PROFILER installed. I believe it comes as a seperate package.
To start the profiler:
SQL> execute dbms_profiler.start_profiler('your_procedure_name');
Run your stored procedure:
SQL> exec your_procedure_name
Stop the profiler:
SQL> execute dbms_profiler.stop_profiler;
This will show you all statements in your store procedure and their associated run time, and this way you can narrow down the problem to possibly a single query that is causing the difference.
Here is the Oracle doc on DBMS_PROFILER:
Oracle DBMS PROFILER
If you are new to oracle then you can use dbms_output or use a logging table to store intermediate execution times, that way you will know which SQL is causing the issue.
declare
run_nbr number;
begin
run_nbr = 1; -- or get it from sequence
SQL1;
log(run_nbr ,user,'sql1',sysdate);
SQL2;
log(run_nbr ,user,'sql2',sysdate);
commit;
end;
here log procedure is nothing but simple insert statements which will insert into a table say "LOG" and which has minimal columns say run_nbr, user, sql_name, execution_date
procedure log(run_nbr number, user varchar2, sql_name varchar2, execution_date date)
is
begin
insert into log values(run_nbr, user, sql_name, execution_date);
-- commit; -- Un-comment if you are using pragma autonomous_transaction
end;
This is little time consuming to put these log statements, but can give you idea about the execution times. Later once you know the issue, you simply remove/comment these lines or take a code backup of your original procedure without these log statements and re-compile it after pin-pointing the issue.
I would check the execution plan of the query, maybe there are profiles in there that are not always used.
or if that doesn't solve it, you can also try tracing the session that calls the SP from the frontend. There's a very good explanation about tracing here: http://tinky2jed.wordpress.com/technical-stuff/oracle-stuff/what-is-the-correct-way-to-trace-a-session-in-oracle/
I've a script that I am using to build/drop tables and basically setting up the entire schema.
After googling, I still can't figure out how to run a stored procedure.
The script is a .txt file, and I run it using Apex SQL Oracle.
If I write only this line in a script:
execute procedurename(1); --where 1 is paramter.
You have requested to run a script that does not contain any runnable
statements.
SQL>create or replace procedure procedurename(p_num number)
as
begin
null;
end;
/
Procedure created.
SQL>execute procedurename(1);
PL/SQL procedure successfully completed.
everything seems ok on SQLPLUS with oracle 11.
so it must be an apex thing.
Since execute is a sqlplus statement ,try calling the procedure using begin-end PLSQL block in Apex SQL
BEGIN
procedurename(1);
END;
/
save this in a file proc_call.sql and then call it in your script like
#C:\proc_call.sql
where C: is the sample path
For some information refer the below link
https://forums.oracle.com/forums/thread.jspa?threadID=618393
I'm trying to run multiple ddl statements within one Execute Immediate statement.
i thought this would be pretty straight forward but it seems i'm mistaken.
The idea is this:
declare v_cnt number;
begin
select count(*) into v_cnt from all_tables where table_name='TABLE1' and owner = 'AMS';
if v_cnt = 0 then
execute immediate 'CREATE TABLE TABLE1(VALUE VARCHAR2(50) NOT NULL) ALTER TABLE TABLE1 ADD (MYVAL2 NVARCHAR2(10))';
end if;
end;
however this results in an error
ORA-00911: invalid character
ORA-06512: at line 10
Each of the statements within the batch run fine if i execute them by themselves. and if i take this statement and execute it, it will run fine (with the ; between the 2 statements). If i remove the ; between statements i get a different error about invalid option
the plan is that i'll be able to build a table, export the table schema for this table including all it's alter statements, and then run the batch against another system as part of an install/update process.
So, how do i batch these DDL statements within a single execute immediate? Or is there a better way to do what i'm needing?
I'm a bit of a Oracle newb, i must admit. Thank you all for your patience.
The semicolon is not part of Oracle's SQL syntax. SQL*Plus and other client side tools use semicolon to signal the end of a SQL Statement, but the server doesn't see it.
We can force SQL*Plus to pass the semicolon to the DB:
SQL> set sqlterminator off
SQL> select * from user_tables;
2 /
select * from user_tables;
*
ERROR at line 1:
ORA-00911: invalid character
If i take this statement and execute it, it will run fine (with the ; between the 2 statements) The client tool you are using, breaks it into two calls to the DB.
So, I don't think it is possible to pass multiple statements inside an execute immediate.
I suppose one could call execute immediate with a string containing an anonymous PL/SQL block, with individual calls to execute immediate inside it ... and I don't know what the point of doing that would be. ;)
Why do you need a single EXECUTE IMMEDIATE call? Surely just do it as 2 calls?
Bear in mind that each DDL statement contains an implicit COMMIT, so there's no concurency benefit to doing it as a single call.
Also, why not just set up the table correctly in the first call? You could do...
CREATE TABLE TABLE1(VALUE VARCHAR2(50) NOT NULL, MYVAL2 NVARCHAR2(10))
...instead of needing 2 calls.
Also, have you looked at DBMS_METADATA... it can generate DDL for objects such as tables for you.