TEMP table in stored procedure oracle 11g - sql

Is there any way to create a temp table with the stored procedure and use the same in the ref cursor in the same stored procedure.
I wrote something like below, it's not working....
CREATE OR REPLACE PROCEDURE USP_TEST(
CUR_QUOTE OUT SYS_REFCURSOR) AS
BEGIN
CREATE GLOBAL TEMPORARY TABLE users1 ON COMMIT PRESERVE ROWS
AS
SELECT 'rb#bot.com' FROM DUAL;
OPEN CUR_QUOTE FOR
SELECT DISTINCT CREATEDBY
FROM QUOTE
WHERE TRUNC(DATEOFENQUIRY)=TRUNC(SYSDATE-1) AND CREATEDBY = users1.EMAIL;
END;
And delete the temp table at the end.
Please suggest with some sample code...
Keep coding :)

If you drop the table then the cursor is invalidated.
From 18c you can use private temporary tables:
create or replace procedure usp_test
( cur_quote out sys_refcursor )
as
begin
execute immediate
'create private temporary table ora$ptt_demo' ||chr(10)||
'on commit drop definition as' ||chr(10)||
'select sysdate -1 as dateofenquiry, ''rb#bot.com'' as createdby' ||chr(10)||
'from dual';
open cur_quote for
'select distinct createdby from ora$ptt_demo where trunc(dateofenquiry) = trunc(sysdate - 1)';
end;
Note that the table name must have the prefix defined by the PRIVATE_TEMP_TABLE_PREFIX parameter (default ORA$PTT_), and you must commit before calling the procedure a second time.

Related

Using Alter Statement from a Table in oracle

I have a table like having one column containing this data
Dummy Column
Alter PACKAGE ABC COMPILE;
Alter PACKAGE CDE COMPILE;
Alter PROCEDURE ABC COMPILE;
Alter TRIGGER ABC COMPILE;
I want to make a script such that when i run that it will execute the alter statements line by line and perform the DDL operations.
Something like this should work, obviously assuming you have real DDL statements stored in that dummy column.
for loop over the column when the value is not null
replace the ; by nothing in order to use execute immediate
Example
declare
vsql table.dummy_column%type;
begin
for h in ( select dummy_column from table where dummy_column is not null )
loop
vsql := replace(h.dummy_column,';','');
execute immediate vsql;
end loop;
end;
/

Can't create a table and select from it while in a plsql procedure in oracle

create or replace procedure sp_test as
begin
CREATE TABLE T AS SELECT col1,col2 FROM t1;
FOR N IN (SELECT * FROM T) LOOP
UPDATE t1 SET t1.col1='value' where col2='value2';
END LOOP;
drop table T;
end;
/
I need to select data into t table from a t1 table in order to apply some modifications, and merge those modifications in t1 table (origin table) before deleting table t.
I m getting this error : PLS-00103
You need to use execute immediate for any ddl inside any pl/sql block. Try the below code:
create or replace procedure sp_test
is
begin
Execute Immediate 'CREATE TABLE T AS SELECT col1,col2 FROM t1';
FOR N IN (SELECT * FROM T) LOOP
Execute immediate 'UPDATE t1 SET t1.col1=''value'' where col2=''value2''';
END LOOP;
execute immediate 'drop table T';
end;
/
Thanks everybody for your contribution, I tried something that works :
A cursor for update.
Thanks for help :)

Procedure for truncate and insert in sql

I have a table- Event_name.
select * from Event_name
I have to truncate the data and insert fresh data daily.
Can someone tell me how to write a stored procedure for truncating and inserting data into table-Event_name?
The generic approach is
Create procedure proc_name
as
Begin
Truncate table Event_name;
insert into Event_name(col_list)
select col_list from source_table;
End;
Try this:
create or replace procedure myProcedure
AS
BEGIN
execute immediate 'truncate table Event_name';
insert into Event_name select * from Event_name;
END;

PLSQL Call Procedure If Exists Clause

I'm using Oracle 9i.
Cue pseudo-code!
I have Stored Procedure A:
PROCEDURE stored_proc_a
IS
BEGIN
insert into...
END;
Then, I have Stored Procedure B:
PROCEDURE stored_proc_b
IS
BEGIN
stored_proc_a
WHERE NOT EXISTS (SELECT * FROM...);
END;
As you can see from my pseudo-code, I would like to call procedure A from procedure B, if a given row does not exist in a table.
I can't find any documentation that would suggest that the WHERE EXISTS clause can be used with a procedure call (the examples show its use with INSERT, UPDATE and DELETE).
Can I use WHERE EXISTS with a procedure call, and if not, what would be the correct code to do a procedure call based on the absence of a particular record in a table?
The correct way of doing this is the following:
PROCEDURE stored_proc_b
IS
num_rows number;
BEGIN
select COUNT(*) into num_rows
FROM my_table
WHERE my_table.xyz = 123; -- (whatever is appropriate)
if num_rows < 1
then
stored_proc_a;
end if;
END;
Figured this out thanks to Nicholas Krasnov and WBAR for their info on other posts.
Another way of achieving the same, in case you you want to call it for multiple rows and want to use data from Table in procedure B-
PROCEDURE stored_proc_b
IS
BEGIN
FOR rec IN (SELECT COL1 FROM <<TABLE1>> T1 WHERE NOT EXISTS (SELECT * FROM <<TABLE2>> T2...WHERE T1.JOIN_COL = T2.JOIN_COL))
LOOP
stored_proc_a;
END LOOP;
EXCEPTION
WHEN OTHERS THEN
rollback;
END;

Oracle Stored Procedure with Alter command

I am trying to build an Oracle stored procedure which will accept a table name as a parameter. The procedure will then rebuild all indexes on the table.
My problem is I get an error while using the ALTER command from a stored procedure, as if PLSQL does not allow that command.
Use the execute immediate statement to execute DDL inside PL/SQL.
create procedure RebuildIndex(index_name varchar2) as
begin
execute immediate 'alter index ' || index_name || ' rebuild';
end;
I tested this code; it works.
Documentation.
Passing Schema Object Names As Parameters
Suppose you need a procedure that
accepts the name of any database
table, then drops that table from your
schema. You must build a string with a
statement that includes the object
names, then use EXECUTE IMMEDIATE to
execute the statement:
CREATE TABLE employees_temp AS SELECT last_name FROM employees;
CREATE PROCEDURE drop_table (table_name IN VARCHAR2) AS
BEGIN
EXECUTE IMMEDIATE 'DROP TABLE ' || table_name;
END;
/
Use concatenation to build the string,
rather than trying to pass the table
name as a bind variable through the
USING clause.
In addition, if you need to call a
procedure whose name is unknown until
runtime, you can pass a parameter
identifying the procedure. For
example, the following procedure can
call another procedure (drop_table) by
specifying the procedure name when
executed.
CREATE PROCEDURE run_proc (proc_name IN VARCHAR2, table_name IN VARCHAR2) ASBEGIN
EXECUTE IMMEDIATE 'CALL "' || proc_name || '" ( :proc_name )' using table_name;
END;
/
If you want to drop a table with the
drop_table procedure, you can run the
procedure as follows. Note that the
procedure name is capitalized.
CREATE TABLE employees_temp AS SELECT last_name FROM employees;
BEGIN
run_proc('DROP_TABLE', 'employees_temp');
END;
/
Here are a couple of possibilities. First, you would have to treat the SQL as dynamic SQL. Second, Oracle DDL statements cannot be run in a transaction (or, they terminate the current transaction and cannot themselves be rolled back). This may affect whether you can use them in stored procedures, or where you can use stored procedures that contain them.
If none of the above apply at all - there could easily be something else astray - I suggest posting some code.