sql oracle procedure IN OUT parameter, how to execute it - sql

my procedure looks like this:
create or replace procedure odcitaj_surovinu_zo_skladu
(
v_id_suroviny IN surovina.id_suroviny%TYPE,
odcitaj IN OUT number
)
as
begin
...//some code here
odcitaj:=odcitaj-22;
...//some code here
end;
Procedure compiled w/o errors. I'm trying to execute it as:
execute odcitaj_surovinu_zo_skladu(1,200);
But it gives error, that '200' can't be used as target of assigment.
So how to execute it? Does ODCITAJ even need to be IN OUT? Cause i know that, if it was just IN , then it would act as constant and i won't be able to assign it anything

As Dmitry Bychenko said, you have to use a variable as the target of an OUT or IN OUT parameter, you can't provide a constant. Your parameter does need to be IN OUT since you're modifying it in the procedure. You can either use an anonymous block:
declare
l_odcitaj number;
begin
l_odcitaj := 200;
odcitaj_surovinu_zo_skladu(1, l_odcitaj);
-- do something with the updated value of l_odcitaj
end;
/
If you want to use the SQL*Plus/SQL Developer execute shorthand wrapper for an anonymous block you can declare a bind variable instead:
variable l_odcitaj number;
exec :l_odcitaj := 200;
exec odcitaj_surovinu_zo_skladu(1, :l_odcitaj);
Notice that the variable name has a colon in front when it is set and when the procedure is called, because it is a bind variable.
If you want you can then use that updated bind variable in other calls, or print it's post-procedure value:
print l_odcitaj
If the updated value - from odcitaj:=odcitaj-22; - doesn't need to be returned and is only used inside the procedure, you could declare the argument as IN and have a local variable which you set from the argument and then manipulate and use in the procedure.
create or replace procedure odcitaj_surovinu_zo_skladu
(
v_id_suroviny IN surovina.id_suroviny%TYPE,
v_odcitaj IN number
)
as
l_odcitaj number;
begin
l_odcitaj := v_odcitaj;
...//some code here
l_odcitaj:=l_odcitaj-22;
...//some code here
end;
/
You could then call the procedure with constant values. It just depends whether the caller needs to know the modified value.

Related

How to declare variables in procedure in PL/SQL

In PL/SQL I have learned that there are two ways to define procedures like below.
Method 1
DECLARE
a number;
PROCEDURE print(mynum number) IS
BEGIN
dbms_output.put_line(mynum);
END;
Method 2
CREATE print(mynum number) IS
BEGIN
dbms_output.print_line(mynum);
END;
But only in method 2, the procedure will store in DBMS as we can call it again and again. What is the difference between two different methods of creating a PLSQL procedure and how we can create and save the store procedure in DBMS which consists of declared variables?
Although you posted invalid syntax, OK - I think I understand the question.
If you want the procedure to be stored, you have to use what you called "Method 2", e.g.
create or replace procedure print (mynum number) is
a number; --> locally declared variable
begin
a := mynum * mynum;
dbms_output.put_line(mynum);
dbms_output.put_line(a);
end;
/
The first piece of code ("Method 1") represents an anonymous PL/SQL block whose contents is "lost" at the end of your session (i.e. when you disconnect).

Variable scoping in BigQuery stored procedure

I am trying to create nested BEGIN..END blocks within the body of BigQuery stored procedure. The code is as follows:
CREATE OR REPLACE PROCEDURE dataset.proc(IN p_var1 INT64, OUT out_param STRING)
BEGIN
DECLARE p_abc INT64;
DECLARE p_bcd INT64;
BEGIN
DECLARE p_abc INT64 DEFAULT 0; //Error Here : re-declaration cannot occur.
WHILE (p_abc <= p_bcd) DO
BEGIN
SET p_abc = p_abc + 1;
END;
END WHILE;
END;
END;
The above stored procedure doesn't compile because of the redeclaration. Unlike in traditional databases, like Netezza or Teradata, I can easily perform such type of variable scoping.
Is there some way to do this on BigQuery or not possible at all?
The documentation says:
It is an error to declare a variable with the same name as a variable declared earlier in the current block or in a containing block.
So I would say it is impossible to create a variable with the same name in the case you described.

Assign value to value of a variable in SQL

I have a variable called LV_MAIN which is having value as LV_TEMP and now I want to assign value to LV_TEMP and write select for LV_TEMP. How can I achieve this?
To explain in detail:
LV_MAIN := LV_TEMP
and now I want to assign:
LV_TEMP := '7'
and want to execute:
SELECT :LV_TEMP FROM DUMMY;
How can I do that?
To execute SQL Script, a "logic container" is required.
This "logic container" can be a trigger, a stored procedure, a table function, or an anonymous block.
For simple once-off queries or prototyping, the anonymous block is the option most readily usable:
DO BEGIN -- this indicates the start of the anon. block
DECLARE lv_temp NVARCHAR(2) := '7';
SELECT
:lv_temp
FROM
DUMMY;
END; -- this indicates the end of the anon. block

Why does invoking procedure that uses REGEX_SUBSTR through PLSQL code block return an extra '¬' char?

Editing in PLSQL.
I've got the following procedure:
SET SERVEROUTPUT ON
CREATE OR REPLACE PROCEDURE StringTest(StringToTest IN varchar2)
AS
result varchar2(100);
BEGIN
result := REGEXP_SUBSTR(StringToTest, '[a-zA-Z0-9]{1,}\/?\s?\w*(\/\d{4})?',1,1);
DBMS_OUTPUT.PUT_LINE('Result is ' || result);
END;
/
The purpose of this procedure is to take in a string, match it with the regex, and then return the first match in the string. I understand for this example the regex is more complicated than it needs to be, but that is because I have truncated the code to its simplest form. The actual code is much more complex, and therefore the regex looks more complex than it needs to for this example.
When I invoke the procedure through a PLSQL code block such as
SET SERVEROUTPUT ON
DECLARE
String1 varchar2(100);
BEGIN
String1 := '(‘Hello’)';
StringTest(String1);
END;
/
I get the following:
Result is Hello¬
When I invoke the procedure through an EXEC statement such as
EXEC StringTest('(‘Hello’)');
I get the following
Result is Hello
The second result is what I expect in both cases. My question is, why does invoking the same exact procedure through a PLSQL code block add the extra ¬ character to the output?

Calling a stored procedure in Oracle with IN and OUT parameters

I have this procedure:
CREATE OR REPLACE PROCEDURE PROC1(invoicenr IN NUMBER, amnt OUT NUMBER)
AS BEGIN
SELECT AMOUNT INTO amnt FROM INVOICE WHERE INVOICE_NR = invoicenr;
END;
So when I run it like this it returns absolutely nothing:
DECLARE
amount NUMBER;
BEGIN
PROC1(1000001, amount);
dbms_output.put_line(amount);
END;
BTW I use DreamCoder for Oracle. Is there a problem with the procedure itself or with the way I call it? There is an entry in the INVOICE table with INVOICE_NR equal to 1000001.
If you set the server output in ON mode before the entire code, it works, otherwise put_line() will not work. Try it!
The code is,
set serveroutput on;
CREATE OR REPLACE PROCEDURE PROC1(invoicenr IN NUMBER, amnt OUT NUMBER)
AS BEGIN
SELECT AMOUNT INTO amnt FROM INVOICE WHERE INVOICE_NR = invoicenr;
END;
And then call the function as it is:
DECLARE
amount NUMBER;
BEGIN
PROC1(1000001, amount);
dbms_output.put_line(amount);
END;
I had the same problem. I used a trigger and in that trigger I called a procedure which computed some values into 2 OUT variables. When I tried to print the result in the trigger body, nothing showed on screen. But then I solved this problem by making 2 local variables in a function, computed what I need with them and finally, copied those variables in your OUT procedure variables. I hope it'll be useful and successful!
Go to Menu Tool -> SQL Output, Run the PL/SQL statement,
the output will show on SQL Output panel.
As per my knowledge, a colon (":") should precede any output variable while executing stored procedures, so invocation should look like this: PROC1(1000001, :amount);
DECLARE
amount NUMBER;
BEGIN
PROC1(1000001, :amount);
dbms_output.put_line(amount);
END;
/
hope this helps