Postgres SQL - Output Clause into a scalar variable - postgresql

For the below code which is in SQL server needs to be converted into PostgresSQL. I did try the same way we do in SQL Server but it dint work.
declare #ID table (ID int)
insert into MyTable(ID)
output inserted.ID into #ID
values (1)
So the above code works well in SQL server but when it comes to Postgres it does not work.
Can someone help in converting this code to Postgres ? Also can someone help me in getting a sample SP with inout and out parms in Postgres please.

Assuming this is part of a stored function (or procedure) written in PL/pgSQL, you can use the returning clause as documented in the manual:
....
declare
l_generated_id int;
begin
...
insert into my_table(id)
values (1)
returning id into l_generated_id;
...
end;
But I have to admit that this seems rather unnecessary as the inserted value is hardcoded in the INSERT statement

Related

PL/PostgreSQL how to convert a variable into a table name

So I have a function in PostgreSQL that dynamically selects columns from a dynamic table. I got this solution from this post and it works great other than one thing.
This is inside of a file that is connected to a Node server, and so the $1 and $2 in the second SELECT * FROM represent values passed from there. The issue right now is that I am getting a syntax error that I don't understand (I am newer to SQL so that may be why).
$2 represents the name of the table to be selected from as a string, so for example it could be 'goals'. The error is syntax error at or near "'goals'". I realize that it cannot be a string with single quotes (I believe) and so I am wondering how to convert that variable to be a table name? using "goals" there as well as goals, for example works as expected, though I'm not sure how to do that outside of a function.
CREATE OR REPLACE FUNCTION get_data(user_id INT, table_name anyelement)
RETURNS SETOF ANYELEMENT AS $$
BEGIN
RETURN QUERY EXECUTE
format('SELECT * FROM %s WHERE user_id = $1', pg_typeof(table_name)) USING user_id;
END;
$$ LANGUAGE plpgsql;
SELECT * FROM get_data($1, NULL::$2);
$1 is 5 and $2 is 'goals' for example
After many hours of trying to figure it out, thanks to Adrian's comment, I found MassiveJS (how I'm connecting to my PostgreSQL server) has inline functions to do queries. In my controller file in my server I was able to create a one line function as such:
const data = await db[tableName].where("user_id=$1", [userId])
Didn't know inline SQL existed in MassiveJS, so that was great to find out!

Is it possible to create a Stored Procedure for Select statements?

If no, please suggest efficient alternatives if possible, I'll edit my question and include the source code if requested
If you want to encapsulate a SQL statement into something "callable", then put it into a function
create function get_data(p_some_value int)
returns table (some_number int, some_date date, some_value text)
as
$$
select c1, c2, c3
from some_table
where x1 = p_some_value;
$$
language sql
stable;
A stored procedure is a prepared SQL code that you can save, so the code can be reused over and over again.
Stored Procedure Syntax:
CREATE PROCEDURE procedure_name
AS
sql_statement
GO;
If you have an SQL query that you write over and over again, save it as a stored procedure, and then just call it to execute it.
You can also pass parameters to a stored procedure so that the stored procedure can act based on the parameter value(s) that is passed.

New to Postgres. Can you help me with a couple simple statments?

I'm very familiar with MSSQL but I need to work with some postgres stuff today. The end goal is to return the new id of a table for use elsewhere but since I'm unfamiliar with the syntax of postgress, I seem to be having some trouble.
Problem 1:
in MSSQL I would:
delcare #test_number int
select #test_number = 42
print #test_number
in Postgres I'm trying:
test_number integer;
test_number := 42
print test_number
but it doesnt like the first line:
ERROR: syntax error at or near "test_number"
LINE 1: test_number integer;
If I can figure this out, I think I've got my real problem solved which would be to do something like:
Problem 2:
in MSSQL I would:
declare #new_id int
insert into some_table (data1. data2)
select #new_id = ##identity
-- now use #new_id for w/e you want
in Postgres I'm trying:
new__id integer;
new_id := insert into some_table (data1, data2) returning id;
-- now use new_id for w/e you want
A quick search on Google gives the following answer.
How do you use variables in a simple PostgreSQL script?
It looks like you basically declare an anonymous inline pgsql function in your query. Also looks like it's new to Postgres 9.

TVP - are they used for input and output?

I've started to read the notes on Table Value Parameters
HERE ON MSDN
HERE ON SOMMARSKOG
Can these TVPs be used as input parameters and output parameters?
Is there a point in having them as an output parameter?
I get the feeling it might be possible to have a TVP as output from one stored procedure and then that feeding into another stored procedure - possible?
The syntax of the script which calls the first sproc and then calls the second sproc using the output TVP from the first is the bit I'm unsure of.
EDIT
Apologies for the confusion of my post - it seems that the initial procedures results need to go into the TVP - I thought that the TVP needed to be involved within that sproc. So a model of what I was talking about is the following - hopefully a valid use of TVPs...
CREATE TYPE myfirstTVP AS TABLE (id INT NOT NULL PRIMARY KEY);
GO --<<this sproc will find the ids (+ other fields) that need to be investigated
CREATE PROC test1 as
SELECT 1 UNION
SELECT 2 UNION
SELECT 3;
GO
GO --<<this sproc uses the found ids to do one aspect of the investigation
CREATE PROC test2
#t2 myfirstTVP READONLY
AS
SELECT id*2
FROM #t2;
GO
GO --<<this sproc uses the found ids to do another aspect of the investigation
CREATE PROC test3
#t4 myfirstTVP READONLY
AS
SELECT id*3
FROM #t4;
GO
--<<this is where the TVP is used and the sprocs are called
DECLARE #t3 myfirstTVP ;
INSERT INTO #t3
EXEC test1;
EXEC test2 #t3;
EXEC test3 #t3;
I'm not 100% sure what you want to achieve, but you can in a sense emulate behaviour of 'output' parameters ,
CREATE TYPE LIST_OF_INT AS TABLE (id int not null primary key);
GO
create procedure test1 as
begin
declare #t1 LIST_OF_INT;
insert into #t1 (id) values (1);
select * from #t1;
end;
GO
declare #t2 LIST_OF_INT ;
insert into #t2
EXEC test1;
select * from #t2;
I think you missed this bit from the MSDN link you cited.
Table-valued parameters must be passed as input READONLY parameters to
Transact-SQL routines.

Trying to convert simple execution stored procedure to postgres function - can't get CURRVAL('table_seq') to function

The MySQL Stored Procedure was:
BEGIN
set #sql=_sql;
PREPARE stmt FROM #sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
set _ires=LAST_INSERT_ID();
END$$
I tried to convert it to:
BEGIN
EXECUTE _sql;
SELECT INTO _ires CURRVAL('table_seq');
RETURN;
END;
I get the error:
SQL error:
ERROR: relation "table_seq" does not exist
LINE 1: SELECT CURRVAL('table_seq')
^
QUERY: SELECT CURRVAL('table_seq')
CONTEXT: PL/pgSQL function "myexecins" line 4 at SQL statement
In statement:
SELECT myexecins('SELECT * FROM tblbilldate WHERE billid = 2')
The query used is for testing purposes only. I believe this function is used to get the row id of the inserted or created row from the query. Any Suggestions?
When you create tables with serial columns, sequences are, by default, named as tablename_columnname_seq, but it seems that you're trying to access tablename_seq. So with a table called foobar and primary key column foobar_id it ends up being foobar_foobar_id_seq.
By the way, a cleaner way to get the primary key after an insert is using the RETURNING clause in INSERT. E.g.:
_sql = 'INSERT INTO sometable (foobar) VALUES (123) RETURNING sometable_id';
EXECUTE _sql INTO _ires;
PostgreSQL is saying that there is no sequence called "table_seq". Are you sure that that is the right name? The name you would use would depend on what is in _sql as each SERIAL or BIGSERIAL gets its own sequence, you can also define sequences and wire them up by hand.
In any case, lastval() is a closer match to MySQL's LAST_INSERT_ID(), lastval() returns the most recently returned value from any sequence in the current session:
lastval
Return the value most recently returned by nextval in the current session. This
function is identical to currval, except that instead of taking the sequence name
as an argument it fetches the value of the last sequence used by nextval in the
current session. It is an error to call lastval if nextval has not yet been called
in the current session.
Using lastval() also means that you don't have to worry about what's in _sql, unless of course it doesn't use a sequence at all.