PL/SQL functions with one parameter - oracle

I was wondering if you could help.
I'm at my wits end with this.
I want to create a function that will take one parameter.
Here is my code. I keep getting the error when run:
Error(3,19): PLS-00103: Encountered the symbol ";" when expecting one of thefollowing:
begin function pragma procedure subtype type current cursor delete exists prior external language
Code
set serveroutput on;
CREATE OR REPLACE FUNCTION CheckBookType (
p_book_type TITLES.CATEGORY
) RETURN BOOLAN IS;
BEGIN
IF (p_book_type = 'business') THEN
return true;
ELSE
return false;
END IF;
RETURN v_ReturnValue;
END CheckBookType;

Least verbose solution:
CREATE OR REPLACE FUNCTION CheckBookType (
p_book_type IN TITLES.CATEGORY%type
) RETURN BOOLEAN
IS
BEGIN
return p_book_type = 'business';
END CheckBookType;

Let's see the issues line by line in your code :
set serveroutput on;
It doesn't make any harm, but I don't see how it helps or is required in the context.
p_book_type TITLES.CATEGORY is wrong, since you need to specify that it is a constrained data type using the %TYPE attribute. The correct way is
p_book_type TITLES.CATEGORY%TYPE
Already mentioned above by others, the datatype of return value should be BOOLEAN. and you don't have to put semi-colon after "IS".
The variable to return the boolean value is NOT declared.
v_ReturnValue BOOLEAN;
Remember, using BOOLEAN data type as return will NOT let you use the function in SQL. Since, boolean is NOT a SQL data type. Boolean is PL/SQL data type. You could only use the function in PL/SQL and NOT in SQL.
Your function would look like :
Quite verbose.
CREATE OR replace FUNCTION Checkbooktype (p_book_type titles.category%TYPE)
RETURN BOOLEAN
IS
v_returnvalue BOOLEAN;
BEGIN
IF ( p_book_type = 'business' ) THEN
v_returnvalue:= TRUE;
ELSE
v_returnvalue:= FALSE;
END IF;
RETURN v_returnvalue;
END checkbooktype;
/
Or, without and ELSE, taking return default as FALSE.
Less verbose.
CREATE OR replace FUNCTION Checkbooktype (p_book_type titles.category%TYPE)
RETURN BOOLEAN
IS
v_returnvalue BOOLEAN;
BEGIN
v_returnvalue:= FALSE;
IF ( p_book_type = 'business' ) THEN
v_returnvalue:= TRUE;
END IF;
RETURN v_returnvalue;
END checkbooktype;
/
#APC's solution is least verbose.

Related

Email output node

CREATE COMPUTE MODULE TestFlow_Compute1
CREATE FUNCTION Main() RETURNS BOOLEAN
BEGIN
CALL CopyMessageHeaders();
--CALL CopyEntireMessage();
SET OutputRoot.EmailOutputHeader.To = 'abcd123#gmail.com';
SET OutputRoot.EmailOutputHeader.From = 'xyz456#gmail.com';
SET OutputLocalEnvironment.Destination.Email.SMTPServer ='smtpout.secureserver.net:25';
DECLARE sid INTEGER InputRoot.XMLNSC.emp.eid;
DECLARE track CHARACTER InputRoot.XMLNSC.emp.etid;
DECLARE sname CHARACTER InputRoot.XMLNSC.emp.ename;
DECLARE sorg CHARACTER InputRoot.XMLNSC.emp.eorg;
DECLARE ssal INTEGER InputRoot.XMLNSC.emp.esal;
SET OutputRoot.XMLNSC.Data.Result.cty=PASSTHRU('SELECT city from ITGDB.mssusr14.collector where targetid='||track TO Database.mss);
SET OutputRoot.XMLNSC.Data.Result.id1=sid;
SET OutputRoot.XMLNSC.Data.Result.nme=sname;
SET OutputRoot.XMLNSC.Data.Result.or=sorg;
SET OutputRoot.XMLNSC.Data.Result.sl=ssal;
RETURN TRUE;
END;
CREATE PROCEDURE CopyMessageHeaders() BEGIN
DECLARE I INTEGER 1;
DECLARE J INTEGER;
SET J = CARDINALITY(InputRoot.*[]);
WHILE I < J DO
SET OutputRoot.*[I] = InputRoot.*[I];
SET I = I + 1;
END WHILE;
END;
CREATE PROCEDURE CopyEntireMessage() BEGIN
SET OutputRoot = InputRoot;
END;
END MODULE;
I used above esql code to send data to email output node, but it is not propagating.Could you please suggest me what is the mistake in the code?
I don't see a PROPAGATE call.
PROPAGATE TO TERMINAL 'out' DELETE NONE;
For Example. Hopefully this helps get you moving. I've also had to RETURN FALSE; rather than TRUE to prevent an additional message over the terminal.

Oracle PL/SQL Return in Blocks

Just a question since I can't seem to find the answer somewhere else.
So I got an PL/SQL function which contains a nested block, and within the 2nd level block it got a return value of 1. Does this mean that it will not proceed to the next block and return the value 1 or it will only terminate the current block?
Thanks!
Sample structure for illustration:
FUNCTION EXAMPLE ( sample_variable VARCHAR2)
RETURN NUMBER
IS
BEGIN
BEGIN
/*CODES HERE*/
EXCEPTION
WHEN OTHERS THEN
RETURN 1; //HERE IS THE QUESTION. WHEN I GOT HERE IN RETURN DOES IT TERMINATE THE WHOLE
//FUNCTION AND RETURN 1 OR IT WILL STILL CONTINUE TO BLOCK 2*/
END;
BEGIN /*BLOCK 2*/
/*OTHER CODES HERE*/
RETURN 2;
END;
END
END EXAMPLE;
Terminates the whole function.
From oracle docs:
In a function, the RETURN statement assigns a specified value to the
function identifier and returns control to the invoker, where
execution resumes immediately after the invocation.

PL/SQL How to call a function without getting returned object

I have a function in PL/SQL:
FUNCTION do_something
RETURN BOOLEAN
IS
...
BEGIN
...
END
This function can be called as such:
DECLARE
answer BOOLEAN;
BEGIN
answer := do_something();
END
Now, there are cases, where I don't need the returned boolean. If I don't want to get it and just write:
do_something();
I get PLS-00306 (wrong number of types of arguments in call to DO_SOMETHING)
Is there a way to call it without declaring and setting a new boolean, which I will never use in this case?
Very simple: create a procedure which covers this function
PROCEDURE do_something
IS
dummy boolean;
BEGIN
dummy := do_something();
END;
Sorry, but this is the only way in PL/SQL. This language is very strict in definitions of procedure and function and you cannot make a function call without handling the result. But you can make a procedure as it is shown in example above.
It will define automatically where to choose the function and where the procedure.
EDIT
As far as there are people who do not trust me (sometimes I really tell bad things so doubts are allowed :) ) this is the test:
declare
myresult boolean;
function do_something return boolean
is
begin
return true;
end;
procedure do_something
is
dummy boolean;
begin
dummy := do_something();
end;
begin
myresult := do_something();
do_something();
end;
works well.
Here is a useful alternative to assigning a dummy variable:
DECLARE
FUNCTION f_yes RETURN boolean IS
BEGIN
return true;
END f_yes;
BEGIN
IF f_yes THEN
null;
END IF;
END;
This is slightly more helpful when there are functions of different return types you want to call without using their results. It's also helpful for writing empty IF statements, which could be useful to to simplify code by eliminating possibilities for the real condition you want to match in a later ELSIF.
I'm in the same situation and the shortest solution I've come up is wrapping it in an IF statement:
if do_something then
null;
end if;

Cannot use OracleParameter of type NVarChar with ParameterDirection of Output when calling stored procedure from ADO.NET

I am using ADO.Net to call a stored procedure in an Oracle database. The stored procedure has an out parameter that is a NVARCHAR2. Here is the stored procedure:
CREATE OR replace PROCEDURE VALIDATE_Bin (
machine_dump_name IN NVARCHAR2,
lpn IN NVARCHAR2,
result OUT NUMBER,
message OUT NVARCHAR2)
IS
BEGIN
IF lpn LIKE 'A%' THEN
result := 1;
message := NULL;
ELSE
IF lpn IS NULL THEN
result := 0;
message := 'Failed Read';
ELSE
result := 0;
message := 'Invalid Barcode';
END IF;
END IF;
END;
And here is the c# code to fill in the parameters of the command:
command.Parameters.Add(new OracleParameter("machine_dumper_name",OracleType.NVarChar){Value = "My Dumper"});
command.Parameters.Add(new OracleParameter("lpn", OracleType.NVarChar) { Value ="XYZ1234"});
var resultParam = new OracleParameter("result", OracleType.Number) { Direction = ParameterDirection.Output};
command.Parameters.Add(resultParam);
var messageParam = new OracleParameter("message", OracleType.NVarChar) { Direction = ParameterDirection.Output};
command.Parameters.Add(messageParam);
command.ExecuteNonQuery();
If I execute it like this I get the exception:
System.Exception: Parameter 'message': No size set for variable length data type: String.
No worries I think. Oracle expects a string length on the "message" parameter. So I add a size parameter on the "message" parameter:
var messageParam = new OracleParameter("message", OracleType.NVarChar, 255) { Direction = ParameterDirection.Output};
and then when I run it I get this System.Data.OracleClient.OracleException:
PLS-00306: wrong number or types of arguments in call to 'VALIDATE_Bin'
How the heck am I supposed to call this procedure and get the message out? I think this problem is specific to string data types. Is this a bug? Or am I doing something wrong?
Try
var messageParam = new OracleParameter("message", OracleDbType.NVarchar2,UInt16.MaxValue) { Direction = ParameterDirection.Output};
messageParam.Value = DbNull.Value
After reading one of #psaraj12's comments I realized the problem parameter may not be the "message" parameter after all. After eliminating variables from the stored procedure one by one I discovered a mis-match in parameter names. In the procedure:
machine_dump_name IN NVARCHAR2,
and in the C# code:
new OracleParameter("machine_dumper_name",OracleType.NVarChar)
Thank you for all your ideas everyone! When I used the actual name of the parameter (machine_DUMP_name) everything worked perfectly!

Returning a value in Pascal

For a function to return a value in Pascal the assignment FunctionName := SomeVal; is used. I assume it doesn't stop the function execution in that exact place as return in C does. Is there something similar to C return in Pascal? (I'm using FreePascal compiler)
You can use the Exit procedure.
function Foo (Value : integer) : Integer;
begin
Exit(Value*2);
DoSomethingElse(); // This will never execute
end;
The return code of the end of every program is stored in the EAX register. So you can use Assembly inline on Pascal to return wherever you want to end the program running using!
asm
mov eax,%ERROLEVEL%
end;
I think you can use either the function name itself, "result", or Exit(), but I've only used the result identifier, so don't know if the others will work for you:
function Foo(a, b: Integer): Integer;
begin
result := a + b;
end;
Hope that helps ^^
In canonical pascal (without keyword Exit) you can emulate return via goto:
function Foo (Value : integer) : boolean;
label return;
begin
if Value < 0 then
begin
Foo := false;
goto return;
end;
Calc();
Foo := true;
return:
end;

Resources