Informix: procedure with output parameters? - sql

I searched a lot, but couldn't find anything.. I just want to ask if there's any way to create and call a procedure (Informix) with out parameters. I know how to return one or more values (for procedures and for functions), but this is not what I want. It would be really strange, if Informix does not allow output parameters..
Thanks in advance!
EDIT: Yes, I saw it's possible, but I still can't execute such procedure. For example:
CREATE PROCEDURE mytest(batch INT,OUT p_out INT)
DEFINE inc INTEGER;
LET inc = 1;
LET p_out = 5;
END PROCEDURE;
and what I receive is:
The routine mytest can not be resolved
and this happens only on executing functions with output parameters..

Why do you need 'out' parameters? Informix procedures can return multiple values from a single call (or, in this case, a single value):
CREATE PROCEDURE mytest(batch INT) RETURNING INT AS p_out;
DEFINE inc INTEGER;
DEFINE p_out INTEGER;
LET inc = 1;
LET p_out = batch + inc;
RETURN p_out;
END PROCEDURE;
There are only a limited number of places where you can use an OUT parameter. One is in a query - there is a name SLV (statement local variable) that turns up in some error messages. I believe there's a way to get to OUT parameters via Java (JDBC) too. AFAIK, other APIs do not allow it.
Code written for Informix assumes that it won't need output parameters. Code migrated to Informix from other (impoverished?) systems that do not provide multiple output values from a single procedure need to be rethought to work sensibly with Informix.

Related

Call a stored procedure with OUT parameter within another stored procedure in SAP HANA

I am currently trying to send an Email from a stored procedure I have created using the native sys.staticserver_sendemail_dev function.
But both the procedures have OUT parameters declared when I try to invoke the email procedure in my I get an error stating the parameters are not declared.
I wanted to know how to call a stored procedure without parameters inside another stored procedure.
I understood from your question, that you have two stored procedures, where one calls the other and both have out parameters. This is a valid constellation. Please find a minimum example, which works on SAP HANA Cloud:
CREATE OR REPLACE PROCEDURE TEST_INNER (OUT i INTEGER)
AS
BEGIN
SELECT COUNT(*) INTO i FROM DUMMY;
END;
CREATE OR REPLACE PROCEDURE TEST_OUTER (OUT another_i INTEGER)
AS
BEGIN
DECLARE outparam INTEGER;
CALL TEST_INNER(:outparam);
another_i = :outparam;
END;
CALL TEST_OUTER(?);
If this does not solve your issue, you need to provide more details as well as minimal code snippet similar to the one above to reproduce the issue.

Struggling to create a "stored procedure" beyond INSERT

Whenever I try to call a stored procedure in PostgreSQL that goes beyond inserting data, it takes forever to run, and it isn't that the query is complicated or the dataset is huge. The dataset is small. I cannot return a table from a stored procedure and I cannot even return 1 row or 1 data point from a stored procedure. It says it is executing the query for a very long time until I finally stop the query from running. It does not give me a reason. I can't let it run for hours. Any ideas on what might be happening? I have included stored procedures that I have tried to call.
Non-working example #1:
CREATE PROCEDURE max_duration(OUT maxD INTERVAL)
LANGUAGE plpgsql AS $$
DECLARE maxD INTERVAL;
BEGIN
SELECT max(public.bikeshare3.duration)
INTO maxD
FROM public.bikeshare3;
END;
$$ ;
CALL max_duration(NULL);
Non-working example #2:
CREATE PROCEDURE getDataByRideId2(rideId varchar(16))
LANGUAGE SQL
AS $$
SELECT rideable_type FROM bikeshare3
WHERE ride_id = rideId
$$;
CALL getDataByRideId2('x78900');
Working example
The only one that worked when called is an insert procedure:
CREATE OR REPLACE PROCEDURE genre_insert_data(GenreId integer, Name_b character varying)
LANGUAGE SQL
AS $$
INSERT INTO public.bikeshare3 VALUES (GenreId, Name_b)
$$;
CALL genre_insert_data(1, 'testName');
FUNCTION or PROCEDURE?
The term "stored procedure" has been a widespread misnomer for the longest time. That got more confusing since Postgres 11 added CREATE PROCEDURE.
You can create a FUNCTION or a PROCEDURE in Postgres. Typically, you want a FUNCTION. A PROCEDURE mostly only makes sense when you need to COMMIT in the body. See:
How to return a value from a stored procedure (not function)?
Nothing in your question indicates the need for a PROCEDURE. You probably want a FUNCTION.
Question asked
Adrian already pointed out most of what's wrong in his comment.
Your first example could work like this:
CREATE OR REPLACE PROCEDURE max_duration(INOUT _max_d interval = NULL)
LANGUAGE plpgsql AS
$proc$
BEGIN
SELECT max(b.duration) INTO _max_d
FROM public.bikeshare3 b;
END
$proc$;
CALL max_duration();
Most importantly, your OUT parameter is visible inside the procedure body. Declaring another instance as variable hides the parameter. You could access the parameter by qualifying with the function name, max_duration.maxD in your original. But that's a measure of last resort. Rather don't introduce duplicate variable names to begin with.
I also did away with error-prone mixed-case identifiers in my answer. See:
Are PostgreSQL column names case-sensitive?
I made the parameter INOUT max_d interval = NULL. By adding a default value, we don't have to pass a value in the call (that's not used anyway). But it must be INOUT instead of OUT for this.
Also, OUT parameters only work for a PROCEDURE since Postgres 14. The release notes:
Stored procedures can now return data via OUT parameters.
While using an OUT parameter, this advise from the manual applies:
Arguments must be supplied for all procedure parameters that lack
defaults, including OUT parameters. However, arguments matching OUT
parameters are not evaluated, so it's customary to just write NULL
for them. (Writing something else for an OUT parameter might cause
compatibility problems with future PostgreSQL versions.)
Your second example could work like this:
CREATE OR REPLACE PROCEDURE get_data_by_ride_id2(IN _ride_id text
, INOUT _rideable_type text = NULL) -- return type?
LANGUAGE sql AS
$proc$
SELECT b.rideable_type
FROM public.bikeshare3 b
WHERE b.ride_id = _ride_id;
$proc$;
CALL get_data_by_ride_id2('x78900');
If the query returns multiple rows, only the first one is returned and the rest is discarded. Don't go there. This only makes sense while ride_id is UNIQUE. Even then, a FUNCTION still seems more suitable ...

How should I select or display the out variable from a stored procedure call?

I'm writing a pretty basic stored procedure that just takes values from the sample DB2 database and computes the standard deviation. I wrote the procedure itself just fine, and I can call it without error. But I can't figure out how to actually display my result or select it in a statement. Everything I try results in a syntax error and I haven't been able to find anyone doing this specific task in my google searches.
This is the gist of my code (snipped for brevity):
CREATE PROCEDURE SAL_STD_DEV
(OUT std_dev real)
LANGUAGE SQL
BEGIN
--do stuff
SET std_dev = 10; --changed for simplicity
END#
CALL SAL_STD_DEV(?)#
All this runs, but just CALL doesn't create any output. What's the syntax to SELECT the out variable? I can't put a DECLARE before the CALL because it's not in a stored procedure, and PRINT doesn't work either.
(# is my terminal character because I'm using ; in the stored procedure)
Edit: Both the create procedure and call statements are made in the same SQL file, the database is connect to through localhost and I'm using DB2 11.1.0.1527 and developing in IBM Data Studio 4.1.2.
From wherever the CALL is being made, that feature might present a Result Set, despite apparently not presenting the result of an OUT parameter. If so, then the stored procedure perhaps could be revised to return the OUT value [instead, or additionally] as a result set, so that the interface that accepts the CALL statement as input, might present that result-set. Regardless:
In a statement processor [e.g. that is not a GUI, but] for which SELECT query output is presented, the following scripted requests should likely suffice:
create variable my_real real
;
call SAL_STD_DEV(my_real)
;
select my_real from sysibm.sysdummy1
;

Creating a function in postgresql what return value to use

I'm new to PostgresSQL programming and am trying to create a function called update_docket so that I can call it from an existing stored procedure.
With the help of some great StackOverflow folks I was able to build my update statement as follows:
UPDATE incode_warrants iw
SET warn_docket_no = iv.viol_docket_no
FROM incode_warrantvs iwvs
JOIN incode_violations iv ON iv.viol_citation_no = iwvs.warnv_citation_no
AND iv.viol_viol_no = iwvs.warnv_viol_no
WHERE iw.warn_rid = iwvs.warnv_rid;
In Navicat (My Postgresql interface) I run this query on the database and I get a return message of Affected Rows with a count.
Now I want to take this query and build a function but I'm unsure as to what I should use as the return value. I was guessing at int4, and I tried to build it with return value void but nothing seems to work.
Can someone point me in the right direction of how to create this function so that I can call it from within a very large stored procedure?
I've looked at the Postgresql manual and am admittedly a bit confused and intimidated as I'm not much of a SQL guy.
I believe in the function I need a BEGIN and END for the transaction and I've even tried return 1; but so far I haven't had any luck in successfully saving this function.
Thanks!
Thank you but I am not sure what code you are running. But, if you are doing a generic stored procedure in postgres, you could do something like this:
CREATE OR REPLACE FUNCTION my_function([parameters to be used in stored procedure, if any])
RETURNS boolean AS -- [or you can have it return any data type such as integer]
$BODY$
DECLARE
some_variable text;
some_other_variable integer;
another_variable timestamp;
BEGIN
/*
Put stored procedure here, in this case it would be your update statement
*/
RETURN true; -- or you can return whatever you want based on what you declare above under RETURNS
END; -- closes the BEGIN clause
$BODY$ -- this is simply a delimiter to open and close the actual procedure that runs
LANGUAGE plpgsql;
Hopefully that gives you some idea.... But it would be helpful if you posted whatever you were trying to run.

Executing a Stored Procedure in Oracle

I have a stored procedure, on Toad for Oracle I am calling the procedure
using
SELECT FROM PKGName.ProcedureName(1,'10/10/2010','10/23/2010',7,7)
FROM DUAL
I have 3 output parameter on this procedure as well I am getting an
ORA-00904: PKGName.ProcedureName : Invalid Identifier
Do have to mention the output parameter on the procedure call as well? If yes how can I use it?
You cannot use a procedure in a SELECT statement. Functions yes (with appropriate return types), procedures no. Items in a SELECT list must be expressions, which must resolve to a value. A procedure does not meet this criteria.
And yes, you do need to mention the output variables in your parameter list. The procedure is going to set those parameters to some values, there needs to be a output parameter specified for each to receive them. #schurik shows you how it is usually done in PL/SQL. #Datajam is close to how you'd do it in SQL*Plus, but leaves out the output parameters:
SQL> var num_var number
SQL> var txt_var varchar2(15)
SQL> var txt_var2 varchar2(20)
SQL> exec PKGName.ProcedureName(1,'10/10/2010','10/23/2010',7,7, :num_var, :txt_var, :txt_var2);
PL/SQL procedure successfully completed
num_var
---------------
42
txt_var
-----------------
some text
txt_var2
-------------------
some other text
SQL>
declare
-- declare variables to keep output values
output_par_1 varchar2(100);
output_par_2 number(10);
...
begin
PKGName.ProcedureName(1,'10/10/2010','10/23/2010',output_par_1,output_par_2);
-- display output values
dbms_output.put_line('output_par_1: ' || output_par_1);
dbms_output.put_line('output_par_2: ' || output_par_2);
end;
/
If you want to be able to call procedures from select, wrap it with a function or table function. See here for more details: http://technology.amis.nl/blog/1017/calling-stored-procedures-using-plain-sql-for-when-sql-is-allowed-but-calls-to-stored-procedures-are-not (heck the title is almost an article hehehe).
Yes, you must provide all arguments. Declare a variable of the appropriate type and pass it as an output argument.
You shouldn't really call a procedure using a SELECT statement (and even if you did, the call would be before the FROM part).
Instead, use a SQL*Plus prompt (I think Toad has a built-in SQL*Plus interface):
exec PKGName.ProcedureName(1,'10/10/2010','10/23/2010',7,7);
The code in the question is syntactically wrong, it should be
SELECT PKGName.ProcedureName(1,'10/10/2010','10/23/2010',7,7) FROM DUAL
However, this would only work for functions. But as it's obviously working in Toad I assume the poster actually did have a function. I also made the assumption that using SQL was a prerequisite.
If the point of the question was how to make use of multiple output parameters - try creating a user defined type. Maybe the question should then be renamed to "Calling a procedure with output parameters from SQL in Oracle".
Otherwise simple wrapper function without output parameters would do the job.