CREATE FUNCTION create_user_if_not_exists(_name text, _pass text)
RETURNS void AS
$func$
DECLARE
_dbname TEXT := concat(_name, '_db');
BEGIN
IF EXISTS (SELECT FROM pg_catalog.pg_roles WHERE rolname = _name) THEN
RAISE NOTICE 'Role already exists. Skipping.';
ELSE
CREATE USER _name WITH encrypted password '_pass';
GRANT ALL PRIVILEGES ON DATABASE _dbname TO _name;
END IF;
END
$func$ LANGUAGE plpgsql;
Quando eu corro:
psql --username "$POSTGRES_USER" -c "SELECT create_user_if_not_exists('Foo', 'BAR');"
Eu entendo:
ERROR: database "_dbname" does not exist
Se eu comentar a GRANT ALL
parte, acabo com um usuário chamado _name
em pg_catalog.pg_roles
. Suspeitei _
que fosse o responsável por isso, mas o mesmo acontece com várias sintaxes. Adicionar _name
e _pass
não DECLARE
muda nada.
Por que _name
, _pass
e são _dbname
interpretados como valores em vez de variáveis próprias neste contexto? É uma questão de definição de função, algumas restrições em GRANT
e CREATE
ou por causa da maneira como chamo esta função com psql
?
Depois de ler isto e isto , não consigo entender a diferença entre explicar o que está errado.
Ambiente:psql (PostgreSQL) 17.4 (Debian 17.4-1.pgdg120+2)
Variáveis PL/pgSQL são tratadas como parâmetros em instruções SQL. Mas nem
CREATE USER
nemGRANT
suportam parâmetros — apenasSELECT
,INSERT
, e . PortantoUPDATE
, você terá que construir uma string de consulta usando e executá-la com :DELETE
VALUES
format()
EXECUTE