Execute the command "UPDATE" which is in the variable CLOB - oracle

I keep some commands in CLOB format. I have the command "update WAYBILLS set TARE = 1212 where EXTERNAL_ID = 1212". I want to do it by calling in the process. I want to perform the actions described in this command. But I do not understand how, I will be grateful for the help
declare
l_clob CLOB;
v_sql CLOB;
BEGIN
v_sql := 'update WAYBILLS set TARE = 1212 where EXTERNAL_ID = 1212';
END ;

The easiest way to execute dynamic SQL is to use EXECUTE IMMEDIATE. Use bind variables.
DECLARE
v_sql CLOB;
v_id PLS_INTEGER := 1212;
BEGIN
v_sql := 'UPDATE waybills SET tare = :id WHERE external_id = :id';
EXECUTE IMMEDIATE(v_sql) USING v_id, v_id;
END;
/
If your statements are longer than 32k, then you have to deal with DBMS_SQL.
You can find more information for example here: Database PL/SQL Language Reference

Related

ORA-01008: not all variables bound - "not all variables bound"

This is my plsql block, dynamic SQL. I can't find a reason why it comes up with an error 'no ORA-01008: not all variables bound ORA-06512: at line 23'.
I can't find the error on my EXECUTE IMMEDIATE statement.
DECLARE
form_name VARCHAR2(225) := 'MUST AS';
ad_no VARCHAR2(225) := :ad_no;
sql_stmt VARCHAR2(4000);
sql_output VARCHAR2(4000);
db_table VARCHAR(225) := inp_reminder_pkg.form_db_table(form_name);
col_id VARCHAR(225) := inp_reminder_pkg.get_col_id(form_name);
BEGIN
sql_stmt := '
SELECT :1
FROM #tableName
WHERE advno = :2
AND created = ( SELECT MAX(CREATED)
FROM #tableName
WHERE advno = :2 )'
;
sql_stmt := replace(sql_stmt, '#tableName', db_table);
EXECUTE IMMEDIATE sql_stmt
INTO sql_output
USING col_id, ad_no;
dbms_output.put_line(sql_output);
EXCEPTION
WHEN no_data_found THEN
dbms_output.put_line('no-data');
END;
Let me know what I am missing. thanks you
There are three bind variables (even though two have the same name), you need to send 3 arguments for them in the execute immediate statement.
Note that you probably didn’t mean for the column name to be input as a bind variable, this is something that has to be dynamically executed if you want to have a variable column being selected.
There are two problems with your code:
The dynamic query has two instances of the placeholder :advno so you need to pass two values in the USING clause. Yes this is a bit rubbish, but I guess Oracle felt parsing dynamic SQL is hard enough without asking the compiler to match placeholder names.
We can't pass column names or other identifiers as parameters. We have to break up the statement to reference the column name variable. For the same reason you have the replace() call to substitute the table name.
So you need to change your procedure so it looks like this:
DECLARE
form_name VARCHAR2(225) := 'MUST AS';
ad_no VARCHAR2(225) := :ad_no;
sql_stmt VARCHAR2(4000);
sql_output VARCHAR2(4000);
db_table VARCHAR(225) := inp_reminder_pkg.form_db_table(form_name);
col_id VARCHAR(225) := inp_reminder_pkg.get_col_id(form_name);
BEGIN
sql_stmt := '
SELECT ' || col_id || '
FROM #tableName
WHERE advno = :2
AND created = ( SELECT MAX(CREATED)
FROM #tableName
WHERE advno = :2 )'
;
sql_stmt := replace(sql_stmt, '#tableName', db_table);
EXECUTE IMMEDIATE sql_stmt
INTO sql_output
USING ad_no, ad_no;
dbms_output.put_line(sql_output);
EXCEPTION
WHEN no_data_found THEN
dbms_output.put_line('no-data');
END;

Oracle display resultset of dynamic sql

i am pretty new to oracle and i am searching for two days already for a solution for my problem.
i have a view which should have a dynamic column and table name.
something like that:
DECLARE
plsql_block VARCHAR2(500);
BEGIN
plsql_block := 'SELECT CONCAT('some','column') FROM CONCAT('some','table')';
EXECUTE IMMEDIATE plsql_block
END;
This would work but how to i display the result? I already tried it with DBMS.Output and a Loop but thats not exactly what i want. i need that it is displayed as a normal result set in the GUI when i run this command. Does anyone has a hint for me how i am doing this in oracle?
I am Thankful for every answer
Thanks pat
Actually I don't understand your dynamic query. But as per my understanding this query is multirow result result set. So you need to use BULK collect and iterate throuh the output for just the purpose of display.
There are two approaches
1) Just to display the output.
SET serveroutput ON;
DECLARE
plsql_block VARCHAR2(500);
lv_col1 VARCHAR2(10):='1';
lv_col2 VARCHAR2(10):='2';
type tab_var
IS
TABLE OF VARCHAR2(10);
tab tab_var;
BEGIN
plsql_block := 'SELECT CONCAT('||lv_col1||','||lv_col2||') FROM dual';
EXECUTE immediate plsql_block bulk collect INTO tab;
FOR i IN tab.first..tab.last
LOOP
dbms_output.put_line(tab(i));
END LOOP;
END;
2) Approach will be refactor this into a function and then use it as below.
Creating a Table Type
create or replace
type string_table
IS TABLE OF VARCHAR2(100);
CREATE OR REPLACE
FUNCTION func_mu
RETURN string_table
AS
plsql_block VARCHAR2(500);
lv_col1 VARCHAR2(10):='1';
lv_col2 VARCHAR2(10):='2';
tab string_table;
BEGIN
plsql_block := 'SELECT CONCAT('||lv_col1||','||lv_col2||') FROM dual';
EXECUTE immediate plsql_block bulk collect INTO tab;
RETURN tab;
END;
SELECT * FROM TABLE(func_mu);
If you are on Oracle 12c (with the corresponding Oracle client), you can do this:
declare
l_resultset sys_refcursor;
l_sql_text varchar2(500) :=q'{select 'Hello, 12c!' as greeting from dual}';
begin
open l_resultset for l_sql_text;
dbms_sql.return_result(l_resultset);
end;
(Untested, because I'm not near a 12c command line right now.)

Pl/sql Executing procedures

I am totally new to PL/SQL.
create or replace procedure p1(a in customer.id%type,
b out customer.name%type,
c out customer.dept%type)
is
begin
select name,dept into b,c from customer where id=a;
end;
Its created properly.
But I am not sure how to execute it.
EXEC p1(1);
But this is showing error.
Your procedure has three parameters so you'd need to call it with three parameters. In the case of OUT parameters, you need to pass in variables that will hold the values that are being returned by the procedure.
DECLARE
l_id customer.id%type := 1;
l_name customer.name%type;
l_dept customer.dept%type;
BEGIN
p1( l_id, l_name, l_dept );
<<do something with l_name and l_dept>>
END;
/
There are two ways to execute a procedure.
From the SQL prompt.
EXECUTE [or EXEC] procedure_name;
Within another procedure – simply use the procedure name.
procedure_name;
the procedure have 3 parameters, you can't call it like p1(1) using just one parameter
in your case try something like this
DECLARE
p_name customer.name%type;
p_department customer.dept%type;
BEGIN
p1(1, p_name, p_department);
END;
Output parameters should be stored in variables.
Input, can be variables or directly given in between the ( )
Use dbms_output.put_line to easily show output in your IDE.
DECLARE
p_name customer.name%type;
p_department customer.dept%type;
p_id customer.id%type := 1;
BEGIN
p1(p_id, p_name, p_department);
END;

Calling preocedure by passing DB Link Dynamically

How to pass db link dynamically while calling a procedure?
Execute immediate will work or we need to use dbms_sql?
For DBMS_SQL i seen it used mostly with curosrs :(
Can any one help me ?
You can use EXECUTE IMMEDIATE. Something like
DECLARE
l_dblink_name VARCHAR2(30) := 'YourDBLink';
l_sql_stmt VARCHAR2(1000);
BEGIN
l_sql_stmt := 'BEGIN procedure_name#' || l_dblink_name || ' (:1, :2); END;';
EXECUTE IMMEDIATE l_sql_stmt
USING 17, 42;
END;
assuming that your procedure takes two parameters and you want to call it with parameter values 17 and 42.

Run Stored Procedure in SQL Developer?

I am trying to run a stored procedure that has multiple in and out parameters. The procedure can only be viewed in my Connections panel by navigating
Other Users | <user> | Packages | <package> | <procedure>
If I right click , the menu items are "Order Members By..." and "Create Unit Test" (greyed out). The ability to "Run" the procedure does not seem possible when it's accessed by user.
I have been trying to find an example of how to create an anonymous block so that I can run the procedure as a SQL file, but haven't found anything that works.
Does anyone know how I can execute this procedure from SQL Developer? I am using Version 2.1.1.64.
EDIT 1:
The procedure I want to call has this signature:
user.package.procedure(
p_1 IN NUMBER,
p_2 IN NUMBER,
p_3 OUT VARCHAR2,
p_4 OUT VARCHAR2,
p_5 OUT VARCHAR2,
p_6 OUT NUMBER)
If I write my anonymous block like this:
DECLARE
out1 VARCHAR2(100);
out2 VARCHAR2(100);
out3 VARCHAR2(100);
out4 NUMBER(100);
BEGIN
EXECUTE user.package.procedure (33,89, :out1, :out2, :out3, :out4);
END;
I get the error:
Bind Varialbe "out1" is NOT DECLCARED
anonymous block completed
I've tried initializing the out* variables:
out1 VARCHAR2(100) := '';
but get the same error:
EDIT 2:
Based on Alex's answer, I tried removing the colons from in front of the params and get this:
Error starting at line 1 in command:
DECLARE
out1 VARCHAR2(100);
out2 VARCHAR2(100);
out3 VARCHAR2(100);
out4 NUMBER(100);
BEGIN
EXECUTE user.package.procedure (33,89, out1, out2, out3, out4);
END;
Error report:
ORA-06550: line 13, column 17:
PLS-00103: Encountered the symbol "USER" when expecting one of the following:
:= . ( # % ; immediate
The symbol ":=" was substituted for "USER" to continue.
06550. 00000 - "line %s, column %s:\n%s"
*Cause: Usually a PL/SQL compilation error.
*Action:
With simple parameter types (i.e. not refcursors etc.) you can do something like this:
SET serveroutput on;
DECLARE
InParam1 number;
InParam2 number;
OutParam1 varchar2(100);
OutParam2 varchar2(100);
OutParam3 varchar2(100);
OutParam4 number;
BEGIN
/* Assign values to IN parameters */
InParam1 := 33;
InParam2 := 89;
/* Call procedure within package, identifying schema if necessary */
schema.package.procedure(InParam1, InParam2,
OutParam1, OutParam2, OutParam3, OutParam4);
/* Display OUT parameters */
dbms_output.put_line('OutParam1: ' || OutParam1);
dbms_output.put_line('OutParam2: ' || OutParam2);
dbms_output.put_line('OutParam3: ' || OutParam3);
dbms_output.put_line('OutParam4: ' || OutParam4);
END;
/
Edited to use the OP's spec, and with an alternative approach to utilise :var bind variables:
var InParam1 number;
var InParam2 number;
var OutParam1 varchar2(100);
var OutParam2 varchar2(100);
var OutParam3 varchar2(100);
var OutParam4 number;
BEGIN
/* Assign values to IN parameters */
:InParam1 := 33;
:InParam2 := 89;
/* Call procedure within package, identifying schema if necessary */
schema.package.procedure(:InParam1, :InParam2,
:OutParam1, :OutParam2, :OutParam3, :OutParam4);
END;
/
-- Display OUT parameters
print :OutParam1;
print :OutParam2;
print :OutParam3;
print :OutParam4;
Executing easy. Getting the results can be hard.
Take a look at this question I asked Best way/tool to get the results from an oracle package procedure
The summary of it goes like this.
Assuming you had a Package named mypackage and procedure called getQuestions. It returns a refcursor and takes in string user name.
All you have to do is create new SQL File (file new). Set the connection and paste in the following and execute.
var r refcursor;
exec mypackage.getquestions(:r, 'OMG Ponies');
print r;
For those using SqlDeveloper 3+, in case you missed that:
SqlDeveloper has feature to execute stored proc/function directly, and output are displayed in a easy-to-read manner.
Just right click on the package/stored proc/ stored function, Click on Run and choose target to be the proc/func you want to execute, SqlDeveloper will generate the code snippet to execute (so that you can put your input parameters). Once executed, output parameters are displayed in lower half of the dialog box, and it even have built-in support for ref cursor: result of cursor will be displayed as a separate output tab.
Open the procedure in SQL Developer and run it from there. SQL Developer displays the SQL that it runs.
BEGIN
PROCEEDURE_NAME_HERE();
END;
Use:
BEGIN
PACKAGE_NAME.PROCEDURE_NAME(parameter_value, ...);
END;
Replace "PACKAGE_NAME", "PROCEDURE_NAME", and "parameter_value" with what you need. OUT parameters will need to be declared prior to.
Though this question is quite old, I keep stumbling into same result without finding an easy way to run from sql developer.
After couple of tries, I found an easy way to execute the stored procedure from sql developer itself.
Under packages, select your desired package and right click on the package name (not on the stored procedure name).
You will find option to run. Select that and supply the required arguments. Click OK and you can see the output in output variables section below
I'm using SQL developer version 4.1.3.20
None of these other answers worked for me. Here's what I had to do to run a procedure in SQL Developer 3.2.20.10:
SET serveroutput on;
DECLARE
testvar varchar(100);
BEGIN
testvar := 'dude';
schema.MY_PROC(testvar);
dbms_output.enable;
dbms_output.put_line(testvar);
END;
And then you'd have to go check the table for whatever your proc was supposed to do with that passed-in variable -- the output will just confirm that the variable received the value (and theoretically, passed it to the proc).
NOTE (differences with mine vs. others):
No : prior to the variable name
No putting .package. or .packages. between the schema name and the procedure name
No having to put an & in the variable's value.
No using print anywhere
No using var to declare the variable
All of these problems left me scratching my head for the longest and these answers that have these egregious errors out to be taken out and tarred and feathered.
Can't believe, this won't execute in SQL Developer:
var r refcursor;
exec PCK.SOME_SP(:r,
'02619857');
print r;
BUT this will:
var r refcursor;
exec TAPI_OVLASCENJA.ARH_SELECT_NAKON_PRESTANKA_REG(:r, '02619857');
print r;
Obviously everything has to be in one line..
Using SQL Developer Version 4.0.2.15 Build 15.21 the following works:
SET SERVEROUTPUT ON
var InParam1 varchar2(100)
var InParam2 varchar2(100)
var InParam3 varchar2(100)
var OutParam1 varchar2(100)
BEGIN
/* Assign values to IN parameters */
:InParam1 := 'one';
:InParam2 := 'two';
:InParam3 := 'three';
/* Call procedure within package, identifying schema if necessary */
schema.package.procedure(:InParam1, :InParam2, :InParam3, :OutParam1);
dbms_output.enable;
dbms_output.put_line('OutParam1: ' || :OutParam1);
END;
/
To run procedure from SQL developer-only execute following command
EXECUTE PROCEDURE_NAME;
I had a stored procedure that returned a cursor, in my case it was actually of a custom package type (T_CURSOR, looks like a convention to me) that is defined as REF CURSOR.
There may be a better way to do this, but I defined variables for all the columns of the table that the cursor was iterating, looped the cursor fetching each row into those variables, then printed them out.
SET serveroutput on;
DECLARE
testvar number;
v_cur SYS_REFCURSOR;
ORIGINAL_EMP_NUM NUMBER;
TEMPORARY_EMP_NUM NUMBER;
ORG_UNIT_CODE VARCHAR2(2 BYTE);
MRU_CODE VARCHAR2(10 BYTE);
CTRL_COMPANY_CODE VARCHAR2(10 BYTE);
IS_TEMP_FLAG VARCHAR2(1 BYTE);
BEGIN
testvar := 420;
foo.updates.get_temporary_authorisations(testvar, v_cur);
dbms_output.enable;
dbms_output.put_line(testvar);
LOOP
FETCH v_cur INTO ORIGINAL_EMP_NUM, TEMPORARY_EMP_NUM, ORG_UNIT_CODE, MRU_CODE, CTRL_COMPANY_CODE, IS_TEMP_FLAG;
EXIT WHEN v_cur%NOTFOUND;
dbms_output.put_line(ORIGINAL_EMP_NUM || ',' || TEMPORARY_EMP_NUM || ',' || ORG_UNIT_CODE || ',' || MRU_CODE|| ',' || CTRL_COMPANY_CODE|| ',' || IS_TEMP_FLAG);
END LOOP;
CLOSE v_cur;
END;
I wasn't able to get #Alex Poole answers working. However, by trial and error, I found the following works (using SQL Developer version 3.0.04). Posting it here in case it helps others:
SET serveroutput on;
DECLARE
var InParam1 number;
var InParam2 number;
var OutParam1 varchar2(100);
var OutParam2 varchar2(100);
var OutParam3 varchar2(100);
var OutParam4 number;
BEGIN
/* Assign values to IN parameters */
InParam1 := 33;
InParam2 := 89;
/* Call procedure within package, identifying schema if necessary */
schema.package.procedure(InParam1, InParam2,
OutParam1, OutParam2, OutParam3, OutParam4);
/* Display OUT parameters */
dbms_output.put_line('OutParam1: ' || OutParam1);
dbms_output.put_line('OutParam2: ' || OutParam2);
dbms_output.put_line('OutParam3: ' || OutParam3);
dbms_output.put_line('OutParam4: ' || OutParam4);
END;
--for setting buffer size needed most of time to avoid `anonymous block completed` message
set serveroutput on size 30000;
-- declaration block in case output need to catch
DECLARE
--declaration for in and out parameter
V_OUT_1 NUMBER;
V_OUT_2 VARCHAR2(200);
BEGIN
--your stored procedure name
schema.package.procedure(
--declaration for in and out parameter
V_OUT_1 => V_OUT_1,
V_OUT_2 => V_OUT_2
);
V_OUT_1 := V_OUT_1;
V_OUT_2 := V_OUT_2;
-- console output, no need to open DBMS OUTPUT seperatly
-- also no need to print each output on seperat line
DBMS_OUTPUT.PUT_LINE('Ouput => ' || V_OUT_1 || ': ' || V_OUT_2);
END;
Creating Pl/SQL block can be painful if you have a lot of procedures which have a lot of parameters. There is an application written on python that do it for you.
It parses the file with procedure declarations and creates the web app for convenient procedure invocations.
var out_para_name refcursor;
execute package_name.procedure_name(inpu_para_val1,input_para_val2,... ,:out_para_name);
print :out_para_name;

Categories

Resources