SAP HANA Stored Procedure optional output parameter with text type - stored-procedures

Let's imagine that I have created the stored procedure in SAP HANA database and would like to have optional out parameter with text type, like error details. As I have read to achieve this I should use some default value thus I have done like this:
PROCEDURE "myProcedure"
(
IN inSomeParameter BIGINT,
OUT outResult INTEGER, -- output, result of the operation
OUT outErrorDetail NVARCHAR(32) default ''
)
Unfortunately build failed with the following error:
OUT and IN OUT parameters may not have default expressions
So, I decided to try with null, but it failed the same way. Later I changed the type to integer just to try and it failed exactly same way again.
In the same time this works:
PROCEDURE "myProcedure"
(
IN inSomeParameter BIGINT,
OUT outResult INTEGER, -- output, result of the operation
OUT outErrorDetail TABLE(errorDetails NVARCHAR(32)) default empty
)
but it feels like a huge overkill - to make a table to return only one text value.
Do you have any suggestion how to add optional output parameter?

SQL Script in its current state doesn’t allow for optional OUT parameters.
Why don’t you just set the OUT parameter default value in the procedure body right before the code?
This adds boilerplate code, but you could also use it to convey explicit success messages.

Related

MULE 4 : STORED PROCEDURE : Executing mule flow to run stored procedure returns "The index 1 is out of range"

I am trying to execute a stored procedure in using MULE 4.
It expects two inputs, one is a table value parameter and another is an integer.
For the table value parameter, i am using SQLServerDataTable and specifying the tvpName using the public method setTvpName. After that I add the column metadata and add rows with the provided Arraylist of values.
In the DB:Stored Procedure component I use the syntax
CALL [database_name].[stored_procedure_name(:argument1,:argument 2)]
where argument 1 is the TVP and argument 2 is the integer.
But I get the error :
Message : The index 1 is out of range.
Error type : DB:QUERY_EXECUTION
Any ideas on how to better debug the issue or solve it is appreciated.

Syntax for setting/updating register fields in Map CRDT on server

What is the syntax for setting lwwreg register values in CRDT Map on server side in Riak? I tried a code like below which doesn't seem to be valid:
%% Obj is a map object to which we want to add/set a register "uname" with value
%% "ahmed"
riak_kv_crdt:update(Obj,<<"testing">>,{crdt_op,riak_dt_map,
{update,[{assign,<<"uname">>,<<"ahmed">>}]},undefined})
I get an error about the operation being invalid - I looked around in source code for riak_dt_map.erl but still can't figure out correct syntax:
> riak_kv_crdt:update(Obj,<<"testing">>,{crdt_op,riak_dt_map,{update,
[{assign,<<"uname">>,<<"ahmed">>}]},undefined}).
** exception error: no function clause matching
riak_dt_map:apply_ops([{assign,<<"uname">>,<<"ahmed">>}],
{<<"testing">>,1},
{[{<<"testing">>,1}],
.....
Will appreciate pointers on correct syntax.
Figured it out. The correct syntax is below - the key must be accompanied by the type of the field which is riak_dt_lwwreg in this case, and assign operation must be specified for register value - so, the syntax becomes:
riak_kv_crdt:update(Obj,<<"testing">>,{crdt_op,riak_dt_map,{update,
[{update,{<<"uname">>,riak_dt_lwwreg},{assign,<<"ahmed">>}}]},undefined})

jooq generates not compiled code from Postgres procedures

Now I am trying to use JOOQ in new version of program that communicate with 2 DBs simultaneously. But problem is coming from Postgres procedures which I cant deactivate cause of Routine generation cannot be deactivated, even if I don't need them in my program.
Problem 1
Jooq understand some procedures like a tables. I am not pro with SQL so I don't know why this happens, maybe cause of procedure return type? Code for generate one of procedures that have this "bug":
CREATE OR REPLACE FUNCTION dblink_get_notify(IN conname text, OUT notify_name text, OUT be_pid integer, OUT extra text)
RETURNS SETOF record AS
'$libdir/dblink', 'dblink_get_notify'
LANGUAGE c VOLATILE STRICT
COST 1
ROWS 1000;
ALTER FUNCTION dblink_get_notify(text)
OWNER TO postgres;
Maybe cause of problem is fact that there is another procedure with the same name, but without IN parameter:
CREATE OR REPLACE FUNCTION dblink_get_notify(OUT notify_name text, OUT be_pid integer, OUT extra text)
RETURNS SETOF record AS
'$libdir/dblink', 'dblink_get_notify'
LANGUAGE c VOLATILE STRICT
COST 1
ROWS 1000;
ALTER FUNCTION dblink_get_notify()
OWNER TO postgres;
Problem 2
Some generated classes from procedures have compile errors (procedure above have this bug too )
I will give you another example:
CREATE OR REPLACE FUNCTION bt_page_stats(IN relname text, IN blkno integer, OUT blkno integer, OUT type "char", OUT live_items integer,
OUT dead_items integer, OUT avg_item_size integer, OUT page_size integer, OUT free_size integer, OUT btpo_prev integer,
OUT btpo_next integer, OUT btpo integer, OUT btpo_flags integer)
RETURNS record AS '$libdir/pageinspect', 'bt_page_stats'
LANGUAGE c VOLATILE STRICT
COST 1;
ALTER FUNCTION bt_page_stats(text, integer)
OWNER TO postgres;
JOOQ understands this procedure as a routine. But generated code have identical twice Parameter<Integer> BLKNO field. And what I found strange is constructor of that class:
/**
* Create a new routine call instance
*/
public BtPageStats() {
super("bt_page_stats", Public.PUBLIC);
addInParameter(RELNAME);
addInOutParameter(BLKNO);
addInOutParameter(BLKNO);
addOutParameter(TYPE);
addOutParameter(LIVE_ITEMS);
addOutParameter(DEAD_ITEMS);
addOutParameter(AVG_ITEM_SIZE);
addOutParameter(PAGE_SIZE);
addOutParameter(FREE_SIZE);
addOutParameter(BTPO_PREV);
addOutParameter(BTPO_NEXT);
addOutParameter(BTPO);
addOutParameter(BTPO_FLAGS);
}
Look at double addOutParameter(BLKNO)!
Wooh, think thats all. Hope you can help me with that problems :)
You ran into bug #4055. As of jOOQ 3.6, overloaded table-valued functions generate code that doesn't compile.
But problem is coming from Postgres procedures which I cant deactivate cause of Routine generation cannot be deactivated, even if I don't need them in my program.
That's true, but you can exclude them from the code generator explicitly by name, e.g. by specifying:
<excludes>dblink_get_notify|bt_page_stats</excludes>
More info about the code generator configuration can be found here

Will a default parameter of a function be overwritten when calling the function with other value as parameter?

I'm making a function in Delphi that needs a specific value as parameter, unless it is set when function is called. While te default parameter be overwritten in that case?
example:
function ExampleFunction(b = 3, a){
b*a = c
}
ExampleFunction(15,2)
Will the default parameter(3) be replaced with the given parameter(15)?
Your code does not compile. Its syntax is invalid. It looks rather as though you have written the code in some hybrid of Pascal and C#. I suggest that you fix the question.
What's more, default parameters must appear last in the list. The reason for that is that default parameters allow you to omit an parameter when calling the function. When you do that, the compiler substitutes the missing parameter with the default value. Because parameters are positional, it is not possible to omit a parameter, but then pass another parameter that appears after it in the list.
The documentation, which I urge you to read one more time, says:
Parameters with default values must occur at the end of the parameter list. That is, all parameters following the first declared default value must also have default values.
Now to the question. If you do not omit the parameter, that is if you provide it, then the value you provided is used.
Let's use an example that actually compiles:
function Test(a: Integer; b: Integer = 42): Integer;
begin
Result := a * b;
end;
Then
Test(2) = 84 // parameter b is omitted, default value passed
and
Test(4, 3) = 12

Using the TYPE command inside a Redis / Lua Script

I am attempting to use the Redis TYPE command inside a Lua script (executed via EVAL)
local key_type = redis.call("TYPE", key)
According to the Redis documentation, this should return a string of "none", "zset" etc.
However the type of the returned value is a lua table. Comparing the value to a string always returns false.
I've managed to get around the problem by changing the call to
local key_type = redis.call("TYPE", key)["ok"]
This value is indeed a string and does work in string comparison commands. I am worried that this is a bug in my particular version of Redis and it will break in future versions when I upgrade.
Does anyone know if this is expected behaviour, or a bug?
The TYPE command returns a status reply (a.k.a simple string), e.g "+list\r\n".
On Redis scripting side, call is implemented by luaRedisCallCommand which performs the real Redis command behind the scenes.
Once successfully executed, this function converts the command result with redisProtocolToLuaType.
When a status reply is encountered, this function creates a Lua table with "ok" as key, and the status reply as value (see redisProtocolToLuaType_Status). So:
there is no bug,
this is why redis.call("TYPE", key) is a table (and thus you need to get the value for the "ok" key as you did, to get key's type as a string).
Note: when you directly return the table, Redis takes care to get the value associated to the "ok" key, and returns it as a status reply, e.g:
> EVAL 'return redis.call("TYPE", "foo")'
set
See this code section for more details.

Resources