How can I ask user to enter the input in PostgresSQL/plpgsql?
Important note: PLpgSQL is server side only language - there is not any possibility do any user interactivity operation. You have to collect input on client side before start of PLpgSQL code, and user input push there as parameters.
DO
statement is server side statement, so you cannot do any interactive action there.
DO
statement doesn't support parameters so it is not easy push any parameters inside DO
statement, but is possible with custom configuration variables:
\prompt 'enter some text: ' psqlvar
\o /dev/null
select set_config('psql.psqlvar', :'psqlvar', false);
\o
do $$
DECLARE var text = current_setting('psql.psqlvar');
BEGIN
RAISE NOTICE 'entered text is: %', var;
END;
$$;
The function set_config
is used to moving a content of client variable :psqlvar
to server side - session variable psql.psqlvar
. The content of this server side variable is taken by function current_setting
.
You have to separate in your mind server side and client side content. The DO
statement is evaluated on server side. The psql
\prompt
command is evaluated on client side.
As bad ideas go, asking for user input in a stored procedure is up there with using usernames as session identifiers. This is a really, really bad idea. Yes there are ways in some environmnets to do this. But just because you can does not mean you should. For example I have heard of people using pl/python to make a network connection back to the client computer and ask for more information. However, this is frankly DailyWTF territory. It also assumes a protocol and listener on the client to ask for this request and therefore doesn't work from pgadmin.
Now, DO creates an anonymous function without arguments and immediately executes it. This seems to be where your real problem is.
Your best solution is to just create an actual function with arguments and accept the input there. Then it can be used anywhere. And you can re-use, modify security, etc. This sounds like it is exactly what you need.
Failing that you could preprocess your
do
block before you send it.
Your best design where you want to reuse PL/PGSQL code with inputs is to use a function (see CREATE FUNCTION
) instead of DO
(note you can put these in another schema if that is a concern).