How to handle parameters in SQL PACKAGE? - sql

I have a table which has columns id, name and password.
I made also a SQL PACKAGE for that which looks like (I omitted Package header, since to emphasis my point more clear):
create or replace PACKAGE BODY MEMBER
is
FUNCTION createWith(v_id, v_name, v_password)
return Number
is
BEGIN
Insert into tbl_member(id, name, password)
Values(v_id, v_name, v_password);
return SQL%ROWCOUNT ;
END createWith;
However, since name column is not necessary column(has no 'not null' option), I sometimes I pass only two parameters(id and password). As far as I know, if the numbers of parameter I sending and numbers of declared parameters in function do not match, it should be 'wrong type or number exception', but It works well.
The thing I wonder is how it can automatically handle empty parameter.
Is anyone who knows useful link or its logic, explain this.
//=============================================================
This is first addition
First of all, I guess my question was not clear enough.
So I going to try again.
step 0, make a table with no constrains and options.(also no default values)
step 1, this is the function header.
function creatWith(v_id in varchar2, v_name in varchar2, v_password in varchar2) return number;
step 2, I call this Package in java(it is web application based on Springframework. However, my company call this a 'solution', so I can not open source code).
However, the method which mapped with this Function has only two parameters. like
public void insert(String id, String pw);
step 3, This is the point of question. It occurs an error or not? In my case, it works. But I do not know My company solution handle or Oracle DB automatically does this.
If Oracle does have, can I get some documents for this policy?

It seems that Oracle tries to use "NULL" values for empty parameters. Change the field to NOT NULL and it will start to return an error.
Try declaring a DEFAULT attribute, like:
FUNCTION createWith(
v_id IN NUMBER,
v_name IN VARCHAR2 DEFAULT 'empty',
v_password IN VARCHAR2)
With this, it will write 'empty' for the Name field when the parameter is empty.

For Oracle Database, declare DEFAULT value in the function definition.
FUNCTION createWith(v_id IN NUMBER,
v_name IN VARCHAR2 DEFAULT 'N.A.',
v_password IN VARCHAR2);

Related

what exactly is plsql function returning if it just return returntype

I'm having a hard time understanding the below plsql function. what exactly does the function return and what exactly does the function do?
function getsysparm(a_name varchar2,
a_default varchar2 := null,
a_date sys_params.date_expires%type := null)
return varchar2;
That's not a function, it's just a function declaration, and from the looks of it, probably in a package spec. You need to look in the package body to see the actual code for the function.
Function accepts 3 parameters: one is mandatory (a_name), while another two are optional.
It returns a string (value whose datatype is VARCHAR2), for example "Abby" or "Stack Overflow" or "x".
What does it exactly do? Who knows ... you didn't post any code. See whether
select text
from user_source
where name = 'GETSYSPARM'
returns something you could have a look at.

How pass a local UDT to a remote DB function?

I am trying to use this PLSQL block:
DECLARE
V_LOG_ENTRY I_LOG_ENTRY;
V_LOG_RETURN INTEGER;
BEGIN
V_LOG_ENTRY := I_LOG_ENTRY(arguments...);
V_LOG_RETURN := I_SESSION_LOGGING.WRITE_LOG_ENTRY#REMOTE(V_LOG_ENTRY, 0);
END;
WRITE_LOG_ENTRY is expecting the type I_LOG_ENTRY. This type is present on both the local db and the remote db. They both have the same OID.
When I execute the block, I get the error: PLS-00306: wrong number or types of arguments in call to 'WRITE_LOG_ENTRY'
Signature for WRITE_LOG_ENTRY:
function WRITE_LOG_ENTRY(
P_LOG_ENTRY I_LOG_ENTRY, P_current_log_level INTEGER DEFAULT NULL
)
Thanks
What I was trying to do is not possible.
Please see Referencing Oracle user defined types over DBLINK? as suggested by #kfinity for a different approach.

How to obtain name of input variable of the procedure (PLSQL)

Let's say I have procedure called myProc(variable varchar2);
Then I call it:
exec myProc(actionVariable);
Is there a way, how to obtain 'actionVariable' as a string in procedure myProc? So when I use procedure differently:
exec myProc(anotherVariable);
I'll obtain 'anotherVariable' as a string in procedure myProc.
Thanks. I only found that I can obtain origin variable name with 'select argument_name from user_arguments....'
You can't determine the name your caller assigned to the variable it passed (as far as I know; maybe you could hack something with PL/Scope but it wold be horrible).
I can see three options, depending on how many variations you need. I'm assuming there aren't many from your comment that the name affects which table the procedure works against.
You could pass the variable name, or the bit you're interested in, as a separate parameter:
procedure myProc(variable varchar2, variable_name varchar2) ...
exec myProc(varIDShop, 'Shop');
You could finesse that a little with wrapper procedures for each variant:
procedure myProc(variable varchar2, variable_name varchar2) ...
procedure myProcShop(variable varchar2) is
begin
myProc(variable, 'Shop');
end;
/
exec myProcShop(varIDShop);
... so your call just has to pick the relevant wrapper function to call.
Or you could declare multiple variables, one for each variant, and only set the one that's relevant:
procedure myProc(shop_variable varchar2, office_variable varchar2, ...) ...
exec myProc(shop_variable => varIDShop);
... and then test which is set within the procedure.
The last two would both mean your call still only has one argument, but they are a bit more complex, and have potential to use the wrong variable name or procedure name (cut-and-paste errors). Although so does the first, I suppose.
None of those directly use the variable name in the caller though. But on the other hand, you could call any of them, e.g. for testing, without having to declare a variable at all - just passing a string literal:
exec myProc('Tesco', 'Shop');
exec myProc(shop_variable => 'Sainsbury');
exec myProcShop('Asda');

typeof Equivalent for Object Types in PL/SQL

I'm trying to use OOP and TDD inside of Oracle. Yes, I know that sounds crazy. And, I need some advice.
I'm writing a test for the following constructor method (simplified for the purposes of this question):
CONSTRUCTOR FUNCTION PERSON(p_pidm NUMBER, p_throw_exception NUMBER DEFAULT 0, p_program_id NUMBER DEFAULT 0)
RETURN SELF AS RESULT IS
BEGIN
-- Attach constructor parameters to internal attributes
self.throw_exception := p_throw_exception;
self.program_id := p_program_id;
-- TESTING STUDENT INSTANTIATION
self.student := NEW STUDENT(self.a_pidm);
RETURN;
END;
In the corresponding test, I'll need to verify that self.student is set to a valid instance of STUDENT. In other languages, I do this with a typeof method, but I'm not aware of one in PL/SQL.
So, the question is, does anyone know a function/procedure that I can pass a user-defined type into and get back its class/type name?
Thanks.
You probably want to use the IS OF <<type>> syntax.
Something like
IF l_variable IS OF( student )
THEN
<<do something>>
END IF;

Function as parameter to another function in Postgres

Can I create a user defined function in Postgres either through the C-Language Function API or by using pl/pgsql which accepts a callback function as parameter?
As far as I see there is no way to do this through the C-Language API since it only accepts sql datatypes and there is no datatype for function. But maybe I'm missing something?
Since each function / procedure must have an entry in pg_proc, you can use the primary key for identifying the procedure. This would also eliminate the problems with procedures having the same name but different number of parameters or different parameter types.
Shorthands for this are the types regproc and regprocedure with the associated casts for easier handling. Lookup the manual for these.
Identifying the function and passing it around is no problem:
select 'pg_database_size(oid)'::regprocedure; -- create "reference"
regprocedure
-----------------------
pg_database_size(oid)
Use regprocedure as the parameter type.
The problem I did not yet figure out is how to actually call such a thing in a convenient way.
I think you can't, but since there are no anonymous functions, passing function name should do.
Old question and already has an accepted answer. But it doesn't clearly explain how to do this. So I thought of adding a more clear answer.
Let's assume you pass the callback function's name to your main function as a varchar value.
CREATE OR REPLACE FUNCTION public.get_function_fields(fn_name character varying)
...
...
Now if you want to call this fn_name function inside a query, you need to use EXECUTE command, and properly cast your function name using regproc as below.
EXECUTE 'create temp table if not exists temp_call as select * from ' || fn_name::regproc || '() limit 1';
Important part is this: ...|| fn_name::regproc || '()... As you can see, you have to append the parenthesis and cast the function name with ::regproc.
Hope it will help someone!
--create an being parametered function.
CREATE OR REPLACE FUNCTION public.select1() RETURNS integer
LANGUAGE sql
IMMUTABLE
AS $function$ select 10;
$function$
--create an function with function as input parameter.
CREATE OR REPLACE FUNCTION public.func_func(fn_name text)
RETURNS SETOF parent_tree
LANGUAGE plpgsql
AS $function$
begin
RETURN QUERY EXECUTE
format('select * from parent_tree where parent_id = %s::regprocedure', fn_name);
end
$function$
--Call it.
select * from func_func('select1()');