Print bind variables when using execute immediate - oracle

i'm trying to print out the vSQL variable after the execute immediate statement.
i know the execute immediate statement ll give ORA-00903 because u can not bind variables to tables etc.i just want to print that string after using
statement.
here is my code :
DECLARE
vSQL VARCHAR2(100);
vOwner VARCHAR2(100);
vTableName VARCHAR2(100);
vPartition VARCHAR2(100);
BEGIN
vOwner := 'STG';
vTableName := 'TEMP';
vSQL := 'ALTER TABLE :1.:2 TRUNCATE PARTITION(:3)';
EXECUTE IMMEDIATE vSQL USING vOwner,vTableName,vPartition;
--DBMS_OUTPUT.PUT_LINE(vSQL); -- Something like this
END;
thx for ideas...

As the commenters wrote you can bind only data to fields, you can't bind library object's names/etc.
So I think you can do it only without binding:
DECLARE
vSQL VARCHAR2(100);
vOwner VARCHAR2(100);
vTableName VARCHAR2(100);
vPartition VARCHAR2(100);
BEGIN
vOwner := 'STG';
vTableName := 'TEMP';
vSQL := 'ALTER TABLE ' || vOwner || '.' || vTableName || ' TRUNCATE PARTITION('||vPartition||')';
EXECUTE IMMEDIATE vSQL;
DBMS_OUTPUT.PUT_LINE(vSQL);
END;

If you know an error is going to happen, catch it and then print.
DECLARE
vSQL VARCHAR2(100);
vOwner VARCHAR2(100);
vTableName VARCHAR2(100);
vPartition VARCHAR2(100);
BEGIN
vOwner := 'STG';
vTableName := 'TEMP';
vSQL := 'ALTER TABLE :1.:2 TRUNCATE PARTITION(:3)';
EXECUTE IMMEDIATE vSQL USING vOwner,vTableName,vPartition;
EXCEPTION --The error will get catched here.
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE(vSQL); --This will print exactly 'ALTER TABLE :1.:2 TRUNCATE PARTITION(:3)'
--If you want to print it with the variables do something like:
DBMS_OUTPUT.PUT_LINE('ALTER TABLE ' || vOwner || ', ' || vTableName || ', ' || vPartition;
END;

Related

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 dynamically create record in PL/Sql based on Table name as Input

I want to understand how to create the record type dynamically based on the table name received as input to the procedure.
Ex:
PROCEDURE xxtest(p_table_name IN VARCHAR2)
IS
TYPE t_test_type IS TABLE OF p_table_name%ROWTYPE;
v_test_type t_test_type;
BEGIN
NULL;
END;
If i was at your place i would try to do simething like that.
create table test_table (f1 number, f2 number);
insert into test_table (f1,f2) values (0,1);
insert into test_table (f1,f2) values (2,3);
select * from test_table
declare
PROCEDURE xxtest(p_table_name IN VARCHAR2) IS
vSql varchar2(4000);
BEGIN
vSql := 'declare ';
vSql := vSql || 'TYPE t_test_type IS TABLE OF '||p_table_name||'%ROWTYPE; ';
vSql := vSql || 'v_test_type t_test_type; ';
vSql := vSql || 'begin ';
vSql := vSql || 'select a1.f1, a1.f2 ';
vSql := vSql || 'bulk collect into v_test_type ';
vSql := vSql || 'from '||p_table_name||' a1; ';
vSql := vSql || 'for i in v_test_type.first..v_test_type.last ';
vSql := vSql || 'loop ';
vSql := vSql || 'dbms_output.put_line(v_test_type(i).f1||'' ''||v_test_type(i).f1); ';
vSql := vSql || 'end loop; ';
vSql := vSql || 'end; ';
dbms_output.put_line(vSQL);
execute immediate vSQL;
END;
begin
xxtest('test_table');
end;
But actually it took almost hour for me and it's real bad question for interview...
May be they don't want to work with you?:)

DBMS_SQL.TO_REFCURSOR equivalent in Oracle 10g

I have the following code :
procedure Replace(sUser in Varchar2,sNomTable in varchar2,sColonne in varchar2,sID in Varchar2,nbCharAlterer IN NUMBER) is
l_cursor NUMBER;
l_return NUMBER;
l_ref_cursor SYS_REFCURSOR;
TYPE t_tab IS TABLE OF VARCHAR2(4000);
l_tab t_tab;
l_tab_Id t_tab;
sChaine VARCHAR2(4000 CHAR);
sqlReq CONSTANT VARCHAR2(1000):= 'select ' || sId || ',' || sColonne || ' from ' || sUser || '.' || sNomTable ;
begin
--
l_cursor := DBMS_SQL.open_cursor;
DBMS_SQL.parse(l_cursor, sqlReq, DBMS_SQL.NATIVE);
l_return := DBMS_SQL.EXECUTE(l_cursor);
-- Connvert from DBMS_SQL to a REF CURSOR.
l_ref_cursor := DBMS_SQL.to_refcursor(l_cursor);
Here I am getting the following error :
pls 00302 component 'TO_REFCURSOR' must be declared
since my oracle version is 10g.
Any idea of how to do the equivalent in Oracle 10g?
Here's how you could use native dynamic sql:
PROCEDURE p_replace(suser IN VARCHAR2,
snomtable IN VARCHAR2,
scolonne IN VARCHAR2,
sid IN VARCHAR2,
nbcharalterer IN NUMBER) IS
v_validate_sid_col_name VARCHAR2(32);
v_validate_scolonne_col_name VARCHAR2(32);
v_validate_suser VARCHAR2(32);
v_validate_snomtable VARCHAR2(32);
sqlreq VARCHAR2(2000);
refcur sys_refcur;
BEGIN
-- Check the input values are valid identifiers (to avoid sql injection)
-- N.B. this does not check they are valid object names!
v_validate_sid_col_name := dbms_assert.qualified_sql_name(sid);
v_validate_scolonne_col_name := dbms_assert.qualified_sql_name(scolonne);
v_validate_suser := dbms_assert.qualified_sql_name(suser);
v_validate_snomtable := dbms_assert.qualified_sql_name(scolonne);
sqlReq := 'select ' || v_validate_sid_col_name || ',' ||
v_validate_scolonne_col_name ||
' from ' || v_validate_suser || '.' || v_validate_snomtable;
-- or maybe you want to use execute immediate to bulk collect into arrays?
OPEN refcur FOR sqlreq;
...
END p_replace;
Note that I've changed the name of the procedure since "replace" is the name of a pre-existing built-in function, and therefore not a very good name to use.
You don't mention what it is you're going to do with the results of your query, so I wasn't sure if opening a ref cursor is what you actually need, or whether bulk collecting via execute immediate would work better for you.

Dynamic call Store Procedure (execute immediate ) Out parameters Problems

I have problem Dynamic Call Store Procedure
v_sql := 'begin '|| p_procname || '(''test1'','' test2 '',:v_output2); end;';
execute immediate v_sql
using out v_output2 ;
dbms_output.put_line(v_output2 || ' ' );
In here ı can call procedure with execute immediate .
But my problem is dynamic bind variable . This values comes from log table then i parse for execute_immediate procedure
v_sql := 'begin '|| p_procname || '(''test1'','' test2'',:v_output2); end;';
v_sql1:= ||using|| 'out v_output2 ' ;
execute immediate v_sql
v_sql1;
It doesnt work like that . How can i make dynamic variables bind , because i call a lot of procedure and thats procedure has different in and out parameters.
I hope you can understand what problem i have .How can i pass this problems thx
here is simple procedure
create procedure test_proc(p_user varchar2, p_code varchar2, p_error varchar2) is
begin
p_error := p_user || p_code;
end;
calling code for same ..
Declare
v_test_proc varchar2(50) := 'test_proc';
p_user varchar2(50) := 'test_name';
p_code varchar2(50) := 'test_code';
p_error varchar2(100);
v_sql varchar2(2000);
begin
v_sql := 'begin ' || v_test_proc || '( :1 ,:2, :3 ); end;';
execute immediate v_sql
using p_user, p_code, out p_error;
dbms_output.put_line(p_error);
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