Error while creating a User Defined Function in postgreSQL using SQL language - sql

I am trying to create the following SQL(the only language I need for my use case) User Defined Function in PostgreSQL.
CREATE function sql_replace(textinput text,pattern character,lefttext integer,righttext integer)
returns text AS $$
DECLARE strlength integer default 0;
BEGIN
strlength = length($1);
return substr($1,1,$3 )
||regexp_replace(substr($1,$3+1,(strlength-$3-$4)),'[0-9]',$2)
||substr($1,(strlength-$4+1),$4 );
-- Additional logic
END;
$$ language SQL VOLATILE;
I have been encountering an error near line 3 in the declare statement. I have tried to push the declare statement inside the begin block but it didn't help. I have also tried to align the input type with SQL but got the same error.

Related

Postgresql Error - Function return type mismatch

I'm looking for some help with a SQL function I am defining under pgAdmin3 for PostGreSQL.
It is a simple function supposed to calculate a ratio given a certain id but when I try to add the function, I get an error message.
Here is the code for the function:
CREATE OR REPLACE FUNCTION data.func_net_exposure(id_fund_arg text)
RETURNS real AS
$BODY$
DECLARE
net_exposure real;
AUM smallint;
BEGIN
AUM := (SELECT sum(cash_fund_total) from main.main_cash where id_fund = id_fund_arg);
net_exposure := (SELECT ROUND(sum(exposure_eur)/(100*AUM)) from main.main_inventory where id_fund = id_fund_arg);
return net_exposure;
END;
$BODY$
And here is the error message I get when I try to add the function:
An error has occurred:
13:13:54: Error: ERROR: return type mismatch in function declared to
return real DETAIL: Function's final statement must be SELECT or
INSERT/UPDATE/DELETE RETURNING. CONTEXT: SQL function
"func_net_exposure"
Any clue on how to solve this error?
The system thinks the function's language is SQL and therefore expects the last statement to be a SELECT or ... RETURNING. The language should be PL/pgSQL. Add a language specification like:
CREATE OR REPLACE FUNCTION data.func_net_exposure(id_fund_arg text)
RETURNS real AS
$BODY$
...
$BODY$
LANGUAGE PLpgSQL;

Using variables from parent in nested postgresql function?

I'm have a pretty long SQL routine that gets a few parameters and runs through a whole bunch of CASE statements. I have the following structure:
DO $$
DECLARE var INTEGER = "someColumn" FROM TABLE LIMIT 1;
BEGIN;
CREATE OR REPLACE FUNCTION pg_temp.fn(var2 boolean) returns decimal AS
$fn$ SELECT CASE WHEN var2 THEN var::decimal ELSE 0::decimal END $fn$ language sql;
$$
And using var inside of fn does not seem to quite work. As in the column does not exist. Is there a way to make it work, am I maybe thinking too complicated?
Edit: fixed the type that was missing. In the original code there is a type declaration, the declaration is not the problem. Using the variable in the nested function is.
First of all. THIS IS NOT THE BEST PRACTICE. It can be done, but it is not recommended to use nested functions.
The problem is that var is in a different scope than the function. You have to "write" the function as an independent unit. You can do this with EXECUTE and FORMAT.
Here is an example of a function that shows var as a message:
DO $$
DECLARE
sql text; -- To "write" the function
var integer := id FROM table_name ORDER BY id LIMIT 1;
BEGIN
-- To make it hapend I use $test$ to set the function.
-- FORMAT is to allocate var into the function through '%s'.
-- you have to use the correct sintax acording to the data type.
sql := FORMAT($test$
CREATE OR REPLACE FUNCTION test() RETURNS void AS $FUNCTION$
BEGIN
RAISE NOTICE '%s';
END; $FUNCTION$ LANGUAGE plpgsql
$test$,var);
EXECUTE sql;
END; $$

PostgreSQL: No function matches the given name and argument types

I have the following procedure:
DROP FUNCTION presAdress();
CREATE FUNCTION presadress() RETURNS VARCHAR(100) AS $$
DECLARE studioName text;
BEGIN
RETURN (
SELECT address AS pres_address
FROM MovieExec
WHERE cert# IN (
SELECT presC#
FROM Studio
WHERE name = studioName)
);
END;
$$ LANGUAGE plpgsql;
I try to run the procedure:
select presadress('Paramount');
But I get the following error message:
ERROR: function presadress(text) does not exist
SQL state: 42883
Hint: No function matches the given name and argument types. You might need to add explicit type casts.
Character: 294
I suspect that this is because there is some kind of error regarding the in parameters of the procedure, but I have been unable to find a solution.
Use a function parameter, like #Gordon demonstrates, but you don't need plpgsql for this at all. And the query can simplified (shorter, faster):
CREATE FUNCTION presadress(_studioname text)
RETURNS text AS
$$
SELECT m.address
FROM studio s
JOIN movieexec m ON m.cert# = s.presc#
WHERE s.name = _studioname
$$ LANGUAGE sql STABLE;
Function volatility can be STABLE.
Related:
How do IMMUTABLE, STABLE and VOLATILE keywords effect behaviour of function?
Difference between language sql and language plpgsql in PostgreSQL functions
PostgreSQL Stored Procedure Performance
I think you want a declaration more like this:
CREATE FUNCTION presadress (v_studioName text)
RETURNS VARCHAR(100) AS $$
BEGIN
RETURN(SELECT address AS pres_address
FROM MovieExec
WHERE cert# IN (SELECT presC#
FROM Studio
WHERE name = v_studioName)
);
END;
$$ LANGUAGE plpgsql;

SQL (Postgres) function definition - RETURNS

I am trying to create a very simple PostgreSQL function, though I keep getting a very strange syntax error. The syntax I use is different from anything I have seen online (though this is the one the textbook uses), and thus I can't figure out why it fails...
This is the SQL:
CREATE OR REPLACE FUNCTION gsum(graphID integer)
RETURNS integer
BEGIN
DECLARE total integer DEFAULT 0
SELECT sum(weight) INTO total
FROM Edge
WHERE gno = graphID
RETURN total;
END;
The error is:
ERROR: syntax error at or near "BEGIN"
LINE 3: BEGIN
^
********** Error **********
ERROR: syntax error at or near "BEGIN"
SQL state: 42601
Character: 68
Your basic mistakes:
DECLARE must come before BEGIN.
Statements need to be terminated with ;.
Function body of a plpgsql function is a string and needs to be quoted. Use dollar-quoting to avoid complications with quotes in the body.
Missing keyword AS.
Missing language declaration LANGUAGE plpgsql.
Type mismatch.
You don't need a default.
This would still return NULL if the sum is NULL.
CREATE OR REPLACE FUNCTION gsum(graphID integer)
RETURNS integer AS
$func$
DECLARE
total integer;
BEGIN
SELECT sum(weight)::int INTO total
FROM edge
WHERE gno = graphID;
RETURN COALESCE(total, 0);
END
$func$ LANGUAGE plpgsql;
And you'd better use a simple SQL function for this like #Clodoaldo advised. Just add COALESCE().
It can be plain SQL in instead of plpgsql
create or replace function gsum(graphid integer)
returns bigint as $$
select sum(weight) as total
from edge
where gno = graphid;
$$ language sql;
Notice that if weight is integer sum will return bigint not integer.
CREATE OR REPLACE FUNCTION gsum(graphID integer)
RETURNS integer AS
$BODY$
DECLARE
total integer DEFAULT 0;
BEGIN
SELECT sum(weight) INTO total
FROM Edge
WHERE gno = graphID;
RETURN total;
END;
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100;

syntax error at or near create when creating a function

So I am creating a function in PostgreSQL for the first time and I am having a problem with the syntax
CREATE OR REPLACE FUNCTION uni() RETURNS INTEGER AS $$
DECLARE
mviews RECORD;
BEGIN
FOR mviews IN SELECT id,universite_adi FROM proaca.a LOOP
INSERT INTO proaca.universite (id,ad,ulke_id)
VALUES (mviews.id,mviews.universite_adi,1)
END LOOP;
RETURN 1;
END;
$$ LANGUAGE plpgsql;
ERROR: syntax error at or near "create"
Line 2: $BODY$CREATE OR REPLACE FUNCTION uni() RETURNS INTEGER AS $$
The syntax error was solved by a_horse in the comments:
missing a ; to terminate the INSERT statement.
You don't need that loop. Just plain sql
create or replace function uni()
returns integer as $$
insert into proaca.universite (id, ad, ulke_id)
select id, universite_adi, 1
from proaca.a
returning 1
;
$$ language sql;