Using OUT parameters in Postgres Stored Procedure - postgresql

Is there any way I can set some value to OUT parameter in Postgres stored procedure? Below is the example what I want to do. In oracle PL/SQL you can use out parameters and set it to any value and return it. After that u can use that value and manipulate it.
CREATE OR REPLACE FUNCTION demo_procedure(p_invoice text, OUT p_out1 integer, OUT p_out2 integer)
returns SETOF record
as
$func$
DECLARE
s_inv_rest integer;
s_state integer;
BEGIN
BEGIN
SELECT "REST_TO_PAY", "STATE"
INTO s_inv_rest, s_state
FROM "INVOICE"
WHERE "INVOICE_REFERENCE" = p_invoice;
EXCEPTION
WHEN NO_DATA_FOUND THEN
p_out1 := 1;
p_out2 := 2;
RETURN;
END;
END;
$func$
language plpgsql;
So in this example for instance if no data is found I want to return some out code and out message.

Related

"Not found" condition being recognized as a type/variable?

CREATE OR REPLACE FUNCTION increaseSomeOfferPricesFunction(IN theOffererID INTEGER, IN numOfferIncreases INTEGER) RETURNS INT AS $$
BEGIN
DECLARE a INTEGER;
DECLARE b INTEGER;
DECLARE c DATE;
DECLARE d INTEGER = 0;
DECLARE NotFound CONDITION FOR SQLSTATE '02000';
When I try to create this stored function, I get the error CONTEXT: invalid type name "CONDITION FOR SQLSTATE '02000'"
I'm confused as to why this is happening, as I'm almost positive the syntax is correct.
This is SQL/PSM language (it is used by MySQL or DB2) - It is not PL/pgSQL. MySQL uses different language for stored procedures than Postgres does.
PL/pgSQL requires variable declaration before BEGIN keyword. Second, PL/pgSQL doesn't support conditions declaration:
CREATE OR REPLACE FUNCTION increaseSomeOfferPricesFunction(IN theOffererID INTEGER,
IN numOfferIncreases INTEGER)
RETURNS INT AS $$
DECLARE
a INTEGER;
b INTEGER;
c DATE;
d INTEGER = 0;
BEGIN
SELECT ...
IF NOT FOUND THEN ...
END IF;
END;
$$ LANGUAGE plpgsql;

Porting strategy pattern from SQL Server to Postgresql

SQL Server has a feature whereby you can call a function or stored procedure with a variable name for the func/proc name. Toy example:
declare #name sysname;
declare #method int = 1;
set #name = IIF(#method = 1, N'Newton', N'Taylor')
declare #sqrt float;
exec #sqrt = #name 42
This will call either Newton or Taylor depending on the value of #method. Using this, it is possible to implement the strategy or command OOP patterns in T-SQL. Where I work, we use it for just that purpose.
Now that I'm learning Postgresql, I'm wondering how I would do something similar in pgplsql. Any tips appreciated!
If all called functions return a single value of the same data type and take a single parameter of the same data type, you can do that with dynamic SQL in Postgres as well:
create or replace function evaluate(p_input integer, p_method text)
returns float
as
$$
declare
l_result float;
begin
execute 'select '||p_method||'($1)'
using p_input
into l_result;
return l_result;
end;
$$
language plpgsql;
select evaluate(42, 'sqrt'); returns 6.48074069840786
select evaluate(1, 'exp'); returns 2.718281828459045
This works with multiple parameters as well:
create or replace function evaluate(p_arg_1 integer, p_arg_2 text, p_method text)
returns float
as
$$
declare
l_result float;
begin
execute 'select '||p_method||'($1, $2)'
using p_arg_1, p_arg_2
into l_result;
return l_result;
end;
$$
language plpgsql;

How to initialize row datatype variables?

I would like to create a function that initialize and return the row datatype of a table as
CREATE FUNCTION get_default_table_row_object()
RETURNS mytable AS $$
DECLARE
row mytable;
BEGIN
row.field1 := 0;
row.field2 := -1;
row.record_reg_id := 1;
row.record_upd_id := 1;
row.record_reg_date := current_timestamp;
row.record_upd_date := current_timestamp;
RETURN row;
END;
$$ LANGUAGE plpgsql;
becuase my table has alot of columns and I need to create dozens of variables at several functions. I would like to use above function as
CREATE FUNCTION some_function() RETURNS VOID AS $$
DECLARE
i_obj1 mytable := get_default_table_row_object(); -- declare and initialize default values
BEGIN
-- function body
END;
$$ LANGUAGE plpgsql;
But this give me the error ERROR: default value for row or record variable is not supported. Has someway to figure it out ?
You can set it in the body instead, like so:
CREATE FUNCTION some_function() RETURNS VOID AS $$
DECLARE
i_obj1 mytable; -- declare only
BEGIN
i_obj1 := get_default_table_row_object(); -- set default values
END;
$$ LANGUAGE plpgsql;

Alias column name in Postgres notify

I am using trigger in Postgres database to call function and send newly inserted row to NodeJs application
CREATE OR REPLACE FUNCTION triggerFunction() RETURNS trigger AS $$
DECLARE
BEGIN
PERFORM pg_notify('tableName', row_to_json(NEW)::text );
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
This returns the whole row in json format. However I need to change one of the column name while this row is returned.
Unfortunately AS keywork doesnt work in the row to json with NEW.COLUMN_NAME AS NEW_COLUMN. How can we achieve the solution for this?
CREATE OR REPLACE FUNCTION triggerFunction() RETURNS trigger AS $$
DECLARE
ret json;
BEGIN
select row_to_json(x) into ret from
(select NEW.abc as def, NEW.jkl, NEW.col3) x;
PERFORM pg_notify('tableName', ret::text );
RETURN NEW;
END;
$$ LANGUAGE plpgsql;

How to get a output of a variable from function in postgresql

I am new to PostgreSQL. I have the query:
---------
DO
$$
DECLARE
l_pin INT;
l_pin1 int;
BEGIN
l_pin := 3;
l_pin1 := 4;
select l_pin,l_pin1;
END;
$$
LANGUAGE PLPGSQL;
--------------------------
from above query am getting an error as
ERROR: query has no destination for result data
HINT: If you want to discard the results of a SELECT, use PERFORM instead.
CONTEXT: PL/pgSQL function inline_code_block line 9 at SQL statement
SQL state: 42601
I need to get the values of l_pin and l_pin1 as output.
What you have there is a DO statement, not a "query" nor a "function". DO statements cannot return anything at all.
How to perform a select query in a DO block?
The displayed error is because you cannot call SELECT in a plpgsql code block without assigning the result. To actually return values from a plpgsql function, use some form of RETURN (explicitly or implicitly).
As minimal example:
CREATE OR REPLACE FUNCTION foo(OUT l_pin int, OUT l_pin1 int)
RETURNS record AS -- RETURNS record is optional because of OUT parameters
$func$
BEGIN
l_pin := 3;
l_pin1 := 4;
RETURN; -- RETURN is optional here because of OUT parameters
END
$func$ LANGUAGE plpgsql;
SELECT * FROM foo();
Related:
Can I make a plpgsql function return an integer without using a variable?
SELECT or PERFORM in a PL/pgSQL function
Returning from a function with OUT parameter
First you can create a new type that can hold multiple values:
CREATE TYPE type_name AS (l_pin INTEGER, l_pin1 INTEGER);
Then you can do something like:
CREATE OR REPLACE FUNCTION function_name()
RETURNS type_name AS $$
DECLARE
result type_name;
BEGIN
/* Code that puts those values into type_name object
i.e.
result.l_pin := 3;
result.l_pin1 := 4;
*/
return result ;
END
$$ language plpgsql