PostgreSQL accessing nested uppercased properties - sql

I've recently switched from mongoDB to postgreSQL and for a while I got stuck with this problem - I can't seem to find a way to access nested property of an object. Yes, I shouldn't be having uppercased column/table names to start with, but I really want to keep naming consistency.
Let's say I have the following db table:
users {
ID: bigint
}
Now let's say I want to get deleted user(old) ID, how do I access this ID?
create or replace function deleted()
returns trigger AS
$body$
begin
perform pg_notify('deleted', ----->WHAT GOES HERE<-----);
return new;
end;
$body$
I've tried filling in placeholder with old."ID", then I get following error:
ERROR: function pg_notify(unknown, bigint) does not exist
LINE 1: SELECT pg_notify('deleted', old."ID")
^
HINT: No function matches the given name and argument types. You might need to add explicit type casts.
QUERY: SELECT pg_notify('deleted', old."ID")
CONTEXT: PL/pgSQL function deleted() line 3 at PERFORM
SQL state: 42883
If I try doing this -> old.ID then I get
ERROR: record "old" has no field "id"
CONTEXT: SQL statement "SELECT pg_notify('deleted', old.ID)"
PL/pgSQL function deleted() line 3 at PERFORM
SQL state: 42703
Also I've tried this: `"old.ID", then I get the following:
ERROR: column "old.ID" does not exist
LINE 1: SELECT pg_notify('deleted', "old.ID")
^
QUERY: SELECT pg_notify('deleted', "old.ID")
CONTEXT: PL/pgSQL function deleted() line 3 at PERFORM
SQL state: 42703
Thank you for your patience.

pg_notify() wants two arguments of text datatype. So you can cast your bigint argument to that datatype:
pg_notify('deleted', (old."ID")::text)

Related

Stored functions postgresql returning table

A novice when it comes to stored procedures/functions. I have searched Google, Stackoverflow, and Youtube and are finding all sorts of examples that are convoluted, some not in English.
I'm trying to understand the basic syntax for a stored function to return a table in Postgresql. In MySql this is elementary but I can't seem to wrap my head around the syntax for Postgresql I have the SQL statement I need to return the rows I want (table), as seen below. I have tried the following code but it doesn't work. Help is much appreciated, thanks in advance.
CREATE OR REPLACE FUNCTION Getcurrent()
RETURNS table AS $schedule$
$BODY$ BEGIN
SELECT *
FROM archived_table
WHERE table_id>=ALL(SELECT table_id FROM archived_table);
RETURN schedule;
END;$BODY$
LANGUAGE plpgsql;
********** Error **********
ERROR: syntax error at or near "AS"
LINE 2: RETURNS table AS $schedule$
^
This is the error message.
I have referenced the following link and have had no luck with this.https://www.postgresql.org/docs/9.1/static/sql-createfunction.html
Im using pgAdminIII, in the public schema, on my company's server.
The desired results is to have the table returned once the function is called.
RETURNS TABLE is not complete, hence the error message.
You can use the RETURNS SETOF <table_name> form, if you intend to return all columns of a table.
Otherwise, you'll need to mention every output column by name and type, with either RETURNS TABLE:
RETURNS TABLE (
col_alias_1 INT,
col_alias_2 TEXT,
col_alias_3 <some_other_type>,
...
)
Or with OUT parameters + RETURNS SETOF RECORD to indicate that you'll (possibly) return multiple rows at once.
Also, if your operation is as simple as a few SQL statements, use LANGUAGE SQL instead:
CREATE OR REPLACE FUNCTION Getcurrent()
RETURNS SETOF archived_table
LANGUAGE SQL
AS $BODY$
SELECT *
FROM archived_table
WHERE table_id>=ALL(SELECT table_id FROM archived_table);
$BODY$;

Return type for function/triggers?

So, after finally getting a bit knowledge about triggers and functions in postgresql, I can't seem to find out whats wrong here:
I create a function for a trigger:
CREATE OR REPLACE FUNCTION upd_totaal_telling()
RETURNS trigger AS
$BODY$
BEGIN
UPDATE totaal_telling
SET telling_getal = (SELECT SUM(pers_salaris) FROM personeel)
RETURNING telling_getal;
END;
$BODY$
LANGUAGE PLPGSQL;
Then I create the trigger for it:
CREATE TRIGGER trig_totaal_telling
AFTER INSERT OR UPDATE ON personeel
FOR EACH ROW
EXECUTE PROCEDURE upd_totaal_telling();
But when I try to insert a value into table, I get this error:
ERROR: query has no destination for result data CONTEXT: PL/pgSQL
function upd_totaal_telling() line 3 at SQL statement
********** Error **********
ERROR: query has no destination for result data SQL state: 42601
Context: PL/pgSQL function upd_totaal_telling() line 3 at SQL
statement
The RETURNING telling_getal at the end of your UPDATE statement is equivalent to having a SELECT telling_getal FROM ... query. If you ran it on its own, you'd get a result set as the output of your query.
But a PostgreSQL function - whether it's a trigger function or not - cannot produce a result set that way, only a return value. A bare SELECT (or RETURNING) does not automatically become the return value of the function. That's what "no destination for result data" means - you are trying to "output" some data, but there is nowhere for that "output" to go.
In this particular case, it seems like your trigger has done its work, and doesn't need to output anything. Since you've defined it to run "after" the target update, it doesn't need to return anything particular, but you do need to return something. To do that, you need to add a RETURN statement; as the page on trigger functions says:
The return value of a row-level trigger fired AFTER ... is always ignored; it might as well be null.
So the line you need to add at the end of your function, after the update statement not part of it, is quite simply:
RETURN NULL;

Why has a query no "destination for result data" in PostgreSQL stored procedure?

I'm new in postgre and I'm with a problem.
I want to great the procedure:
CREATE OR REPLACE FUNCTION autenticarusuario()
RETURNS users AS
$BODY$`
DECLARE
login text;
senha text;
BEGIN
SELECT * FROM users WHERE login_user = login
AND pass_user = senha;
END;
$BODY$
LANGUAGE plpgsql IMMUTABLE
COST 100;
ALTER FUNCTION autenticarusuario()
OWNER TO postgres;
but I always get the message:
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 autenticarusuario() line 6 at SQL statement
********** Error **********
ERROR: query has no destination for result data
SQL state: 42601
Hint: If you want to discard the results of a SELECT, use PERFORM instead.
Context: PL/pgSQL function autenticarusuario() line 6 at SQL statement
The issue here is that you're telling Postgres "Start executing this function, then execute this query". Postgres is complaining because you don't tell it what to do with the query results. You could either use a SELECT INTO statement, or you could use RETURN QUERY to return a single column, like the user id:
CREATE OR REPLACE FUNCTION autenticarusuario()
RETURNS SETOF INTEGER AS
$BODY$`
DECLARE
login text;
senha text;
BEGIN
RETURN QUERY SELECT id
FROM users
WHERE login_user = login
AND pass_user = senha;
END;
$BODY$
LANGUAGE plpgsql IMMUTABLE
COST 100;
If you want to return multiple fields for each record, you can use a similar strategy to what is detailed here and create your own type.
My colleague faced a similar problem. She than used OPEN MYCURS before the select query and RETURN MYCURS after the select query.

Postgresql function not returning a table on select

I have the following postgresql function in which i am trying to return 2 parameters named campusid and campusname.
CREATE OR REPLACE FUNCTION getall(IN a character varying, IN b character varying)
RETURNS TABLE(id character varying, name character varying) AS
$BODY$
BEGIN
if $1 = 'PK' then
SELECT * from table1;
end if;
END
$BODY$
LANGUAGE plpgsql;
But i am getting the following error:
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 "getallcampuses" line 27 at SQL statement
********** Error **********
ERROR: query has no destination for result data
SQL state: 42601
Hint: If you want to discard the results of a SELECT, use PERFORM instead.
Context: PL/pgSQL function "getallcampuses" line 27 at SQL statement
What do i need to change in the function to make it return me a table of values? I have also checked the perform query but i need to return a result.
You must have a destination for the selects, and the function must return a value. Just a SELECT statement does neither. The only use of such a statement, generally, is to test permissions, or make a trigger run, for which the results are not used. You will need to use one of the family of RETURN statements, to get values from the function.
RETURN QUERY( SELECT * from "SIS_campus" );
That will add the results of that query to the function's returning results, and should do what you're after, since you only can return 0 or 1 results. You may need to add a simple RETURN at the very end of the function, as well (despite the docs, I've not quite grokked when that is or isn't needed, myself).

Creating functions in postgresql

I am new to SQL, so please try not to be overly critical about my question, I need to create a function which would return me a table (say for example "machine") , which would have a column called "aggtablename" and the rows would be filled with values derived from a database. Here is what i tried and the following error came....so please help me in making my syntax correct, THANKS..
CREATE FUNCTION aggtable() RETURNS TABLE (machineid, serveraggtablename)
AS $table$
BEGIN
RETURN QUERY
SELECT m.machineid, m.serveraggtablename
FROM machine m
END;
$table$
LANGUAGE plpgsql;
select aggtable();
ERROR: function aggtable() does not exist LINE 1: select aggtable();
^ HINT: No function matches the given name and argument types. You might need to add explicit type casts.
The arguments of the table you're returning do not have any type.
try adding a type such as machineid int.
check this post
How can a Postgres Stored Function return a table
Try this
CREATE TYPE machineType as (machineid int, serveraggtable character varying);
CREATE FUNCTION aggtable() RETURNS SETOF machineType AS
'SELECT m.machineid, m.serveraggtablename FROM machine m;'
LANGUAGE 'sql';
SELECT * FROM aggtable();
https://wiki.postgresql.org/wiki/Return_more_than_one_row_of_data_from_PL/pgSQL_functions