Stored procedure output in select statement - oracle

I'm trying desperately to call an oracle stored procedure and have the output come out looking like they came from a select statement.
The goal is to embed the sql in other software that can execute sql queries.
Here's a sample of the kind of thing I'd like to be able to do.
/* P_DELETE_THIS_TEST IS A STORED PROCEDURE WITH 4 VARCHAR2 PARAMETERS DEFINED AS IN OUT VARIABLES */
DECLARE
char_1 VARCHAR2(255) := 'TEST';
char_2 VARCHAR2(255) := '';
char_3 VARCHAR2(255) := '';
char_4 VARCHAR2(255) := '';
BEGIN
P_DELETE_THIS_TEST(char_1, char_2, char_3, char_4);
SELECT char_1, char_2, char_3, char_4 FROM DUAL;
END;

You can try with dynamic sql.
The following PL/SQL block contains several examples of dynamic SQL:
DECLARE
sql_stmt VARCHAR2(200);
plsql_block VARCHAR2(500);
emp_id NUMBER(4) := 7566;
salary NUMBER(7,2);
dept_id NUMBER(2) := 50;
dept_name VARCHAR2(14) := 'PERSONNEL';
location VARCHAR2(13) := 'DALLAS';
emp_rec emp%ROWTYPE;
BEGIN
EXECUTE IMMEDIATE 'CREATE TABLE bonus (id NUMBER, amt NUMBER)';
sql_stmt := 'INSERT INTO dept VALUES (:1, :2, :3)';
EXECUTE IMMEDIATE sql_stmt USING dept_id, dept_name, location;
sql_stmt := 'SELECT * FROM emp WHERE empno = :id';
EXECUTE IMMEDIATE sql_stmt INTO emp_rec USING emp_id;
plsql_block := 'BEGIN emp_pkg.raise_salary(:id, :amt); END;';
EXECUTE IMMEDIATE plsql_block USING 7788, 500;
sql_stmt := 'UPDATE emp SET sal = 2000 WHERE empno = :1
RETURNING sal INTO :2';
EXECUTE IMMEDIATE sql_stmt USING emp_id RETURNING INTO salary;
EXECUTE IMMEDIATE 'DELETE FROM dept WHERE deptno = :num'
USING dept_id;
EXECUTE IMMEDIATE 'ALTER SESSION SET SQL_TRACE TRUE';
END;

Related

Oracle stored procedure SQL query assign to variable

I have a column containing a SQL query, and I want to assign a record to a different table according to the result of this query. My code is as below.
Can I make such an assignment in the stored procedure?
l_sel_sql := l_sel_query_rec.SQL_QUERY;
sql_query content: apostrophe included
'SELECT MBB_NO AS mbb_no, clob_column AS CLOB1, JSON_OBJECT(MBB_NO RETURNING CLOB) AS DEL_DATA FROM A '
My code is like this:
create or replace procedure SP_DELETED
is
TYPE sql_query_type IS RECORD
(
TABLE_NAME VARCHAR2(100),
COLUMN_NAME VARCHAR2(25),
SQL_QUERY VARCHAR2(2500)
);
TYPE json_data_type IS RECORD
(
MBB_NO NUMBER,
CLOB1 clob,
CLOB2 CLOB,
DEL_DATA CLOB
);
l_sel_query VARCHAR2(2500);
l_sel_query_cur SYS_REFCURSOR;
l_sel_query_rec sql_query_type;
l_sel_sql VARCHAR2 (2500);
l_deleted_cur SYS_REFCURSOR;
l_deleted_rec json_data_type;
r_del_data KV_DELETED%ROWTYPE;
begin
l_sel_query := 'SELECT TABLE_NAME, COLUMN_NAME , SQL_QUERY FROM STORE_PROCEDURE ';
open l_sel_query_cur for l_sel_query;
loop
fetch l_sel_query_cur into l_sel_query_rec;
exit when l_sel_query_cur%notfound;
*l_sel_sql := l_sel_query_rec.SQL_QUERY;*
open l_deleted_cur for l_sel_sql;
loop
fetch l_deleted_cur into l_deleted_rec;
exit when l_deleted_cur%notfound;
r_del_data.TABLE_NAME := l_sel_query_rec.TABLE_NAME;
r_del_data.COLUMN_NAME := l_sel_query_rec.COLUMN_NAME;
r_del_data.TABLE_KEY := l_deleted_rec.MBB_NO;
r_del_data.DELETED_DOCUMENT_JSON := l_deleted_rec.DEL_DATA;
r_del_data.DELETED_DOCUMENT_CLOB1 := l_deleted_rec.CLOB1;
Insert into KV_DELETED
values r_del_data;
end loop;
close l_deleted_cur;
end loop;
close l_sel_query_cur;
end;

oracle dynamic sql evaluate expression in where clause

I am trying to pass an expression into the WHERE clause of my query using dynamic SQL. The expression can contain multiple filters/columns.
Similar to other posts on SO, the following (example 1) works:
DECLARE
where_expression VARCHAR2(40) := q'[filter_column = 'some_value')]';
plsql_block VARCHAR2(500);
BEGIN
plsql_block := 'SELECT column FROM mytable';
EXECUTE IMMEDIATE plsql_block || ' WHERE ' || where_expression;
END;
/
And this approach (example 2) using placeholders does not work:
DECLARE
where_expression VARCHAR2(40) := q'[filter_column = 'some_value')]';
plsql_block VARCHAR2(500);
BEGIN
plsql_block := 'SELECT column FROM mytable WHERE :a';
EXECUTE IMMEDIATE plsql_block USING where_expression;
END;
/
Oracle returns an error: ORA-00920: invalid relational operator at line 8 (EXEC statement).
What am I doing wrong in example 2 and what's the correct way with placeholders?
What am I doing wrong in example 2 and what's the correct way with placeholders?
The placeholder syntax is for passing values to be checked when the statement is executed. The expected usage is something like this:
DECLARE
v_out_1 varchar2(32);
v_out_2 varchar2(32);
plsql_block VARCHAR2(500);
BEGIN
plsql_block := 'SELECT column FROM mytable WHERE filter_column = :a';
EXECUTE IMMEDIATE plsql_block INTO v_out_1 USING 'some value';
EXECUTE IMMEDIATE plsql_block INTO v_out_2 USING 'another value';
END;
/
Whitelist the possible filter columns in a CASE expression:
DECLARE
v_out VARCHAR2(32);
column_name VARCHAR2(30) := 'COLUMN1';
column_value VARCHAR2(30) := 'value1';
sql VARCHAR2(500);
BEGIN
sql := 'SELECT column
FROM mytable
WHERE CASE :name
WHEN ''COLUMN1'' THEN column1
WHEN ''COLUMN2'' THEN column2
WHEN ''COLUMN3'' THEN column3
END = :value';
EXECUTE IMMEDIATE sql INTO v_out USING column_name, column_value;
END;
/

Using variable in FROM clause pl/sql

SET SERVEROUTPUT ON
DECLARE
table_name varchar2(80) := 'dual';
BEGIN
SELECT * FROM table_name WHERE dummy = 'X';
END;
The above code throws error. I want to use a variable in the from clause.
For a dynamic query you can use EXECUTE IMMEDIATE.
DECLARE
table_name VARCHAR2 (80) := 'dual';
v_query VARCHAR2 (200);
BEGIN
v_query := 'SELECT *
FROM ' || table_name || '
WHERE dummy = ''X''';
EXECUTE IMMEDIATE v_query;
END;

How to return a collection from dynamic SQL having RETURNING clause

I have a PL/SQL block like this:
CREATE OR REPLACE TYPE NUMBER_TABLE_TYPE AS TABLE OF NUMBER;
DECLARE
updatedEmp NUMBER_TABLE_TYPE;
sqlstr VARCHAR2(1000);
tableName VARCHAR2(30) := 'EMPLOYEE';
deptId NUMBER := 12;
BEGIN
sqlstr := 'UPDATE '||tableName||' SET SALARY = SALARY * 2 WHERE DEPT_ID = :deptId '||
'RETURNING EMP_ID BULK COLLECT INTO :res';
EXECUTE IMMEDIATE sqlstr BULK COLLECT INTO updatedEmp USING deptId;
END;
RETURNING BULK COLLECT INTO clause would be simple for static DML, however in my application it is a dynamic one. I tried several ways but non of them worked out. Any idea how to achieve this?
CREATE OR REPLACE TYPE NUMBER_TABLE_TYPE AS TABLE OF NUMBER;
DECLARE
updatedEmp NUMBER_TABLE_TYPE;
sqlstr VARCHAR2(1000);
tableName VARCHAR2(30) := 'EMPLOYEE';
deptId NUMBER := 12;
BEGIN
sqlstr := 'UPDATE '||tableName||' SET SALARY = SALARY * 2 WHERE DEPT_ID = :deptId '||
'RETURNING EMP_ID INTO :res';
EXECUTE IMMEDIATE sqlstr
USING deptId RETURNING BULK COLLECT INTO updatedEmp ;
END;

How to assign a table name to a variable and using the same inside immediate execute statement

I am trying to assign table name to a variable and to use the same inside execute immediate statement , please help me with the syntax inside execute statement
scenario is
I am trying to pass a table name as parameter in the procedure and am using them inside execute immediate to write into some other table .
please suggest me the syntax for in parameters and for the execute immediate statement.
My Procedure:
CREATE OR REPLACE PROCEDURE tep
AS
v_sql VARCHAR2(1024) ;
a NUMBER;
b VARCHAR2(30) :='t_stg1_non_silicon_purchace_re';
BEGIN
v_sql := q'[SELECT COUNT(*) FROM b ]';
EXECUTE immediate v_sql INTO a;
DBMS_OUTPUT.PUT_LINE( TO_CHAR(v_sql));
DBMS_OUTPUT.PUT_LINE( TO_CHAR(a));
END;
/
You haven't specified what exactly you want to do with the table name in the execute immediate so see example below of how to "CREATE" a table.
DECLARE
vTableName VARCHAR2(40 CHAR);
vSQL VARCHAR2(1000 CHAR);
BEGIN
vTableName:='MY_TABLE_NAME';
vSQL:='CREATE TABLE ' || vTableName || ' (COL1 NUMBER, COL2 NUMBER)';
EXECUTE IMMEDIATE vSQL;
END;
/
This query may satisfy your requirement. Thanks
CREATE OR REPLACE PROCEDURE tep
AS
v_sql VARCHAR2(1024) ;
a NUMBER;
b VARCHAR2(30) :='t_stg1_non_silicon_purchace_re';
BEGIN
v_sql := 'SELECT COUNT(*) FROM'||' '||b;
EXECUTE immediate v_sql INTO a;
DBMS_OUTPUT.PUT_LINE( TO_CHAR(v_sql));
DBMS_OUTPUT.PUT_LINE( TO_CHAR(a));
END;

Resources