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

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?

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).

Declaring variables dynamically within PL/SQL

The program is to extract numbers from an input string. Eg: ab123cde4f. Now if only the input string has numbers then I will declare a variable of number datatype (to extract the numbers) after checking for numbers within the Begin..End block. If there are no numbers I will not declare any variable and simply give dbms output that the input string does not contain any numbers. Suggest a pl/sql block.
If your questions is, if a variable can be declared within a BEGIN...END block. No, you always need a declare block for that.
However you can use declare inside a BEGIN...END Block as well.
BEGIN
IF 1=1 THEN
DECLARE
v_chr VARCHAR2(100) := 'hello';
BEGIN
dbms_output.put_line(v_chr);
END;
ELSE
DECLARE
v_chr VARCHAR2(100) := 'world';
BEGIN
dbms_output.put_line(v_chr);
END;
END IF;
END;
I wouldn't suggest it though, its much more KISS thingy to just define a variable.

sql oracle procedure IN OUT parameter, how to execute it

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.

Procedures or Functions (Pl/sql)

I am currently learning pl/sql using oracle 10g
I have a certain confusion
When should I use stored procedures and when should i go for functions?
Please help me out with some real world example.
Thank you.
A function returns a value, although that could actually be an object like a cursor.
Also only a function can be defined with the following (as of 11.1):
DETERMINISTIC option, which helps the optimizer avoid redundant function calls.
PARALLEL_ENABLED option, which allows the function to be used safely in slave sessions of parallel DML evaluations.
PIPELINED option, which returns the results of a table function iteratively.
RESULT_CACHE option, which stores function results in the PL/SQL function result cache.
RESULT_CACHE clause, which specifies the data sources on which the results of a function.
So if you need to return multiple values, use a procedure. However be aware that the above five features are then not available.
If you want to include a PL/SQL subprogram in a SQL statement then you probably want a function.
http://docs.oracle.com/cd/B28359_01/appdev.111/b28370/subprograms.htm#CHDBEJGF
DECLARE
l_user_id VARCHAR2(1);
l_received_user VARCHAR2(30);
PROCEDURE print_user_name(user_name_in IN VARCHAR2)
AS
BEGIN
DBMS_OUTPUT.PUT_LINE('The user''s name is: ' || INITCAP(user_name_in));
END print_user_name;
FUNCTION get_user_name(user_id_in IN VARCHAR2) RETURN VARCHAR2
AS
l_user_name VARCHAR2(30);
BEGIN
SELECT 'Amanda'
INTO l_user_name
FROM dual
WHERE dummy = user_id_in;
RETURN l_user_name;
END get_user_name;
BEGIN
-- excute an action --
print_user_name('John');
l_user_id := 'X';
-- hold action's result in a variable --
l_received_user := get_user_name(l_user_id);
-- work with the received result/variable --
DBMS_OUTPUT.PUT_LINE('The received user''s name is: ' || INITCAP(l_received_user));
IF l_received_user = 'John' THEN
DBMS_OUTPUT.PUT_LINE('The received user''s name is John');
ELSE
DBMS_OUTPUT.PUT_LINE('The received user''s name is not John');
END IF;
END;
/*
The user's name is: John
The received user's name is: Amanda
The received user's name is not John
*/
Difference is that sored procedure do something, while functions do something and return result (variable or table).

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