PSQL
SET
variáveis não são interpoladas dentro de strings cotadas em dólar. Não tenho certeza disso, mas acho que não há escapatória ou outro truque para ativar SET
interpolação variável lá. Pode-se pensar que você poderia colocar um
:user
sem aspas entre dois trechos cotados em dólar de PL/pgSQL para obter o efeito desejado. Mas isso não parece funcionar... Acho que a sintaxe requer uma única string e não uma expressão concatenando strings. Pode estar enganado nisso. De qualquer forma, isso não importa. Há outra abordagem (como Pasco observou):escreva o procedimento armazenado para aceitar um argumento PL/pgSQL. Aqui está como seria.
CREATE OR REPLACE FUNCTION foo("user" TEXT) RETURNS void AS
$$
BEGIN
EXECUTE 'GRANT SELECT ON my_table TO GROUP ' || quote_ident(user);
END;
$$ LANGUAGE plpgsql;
Observações sobre esta função:
EXECUTE
gera umGRANT
apropriado em cada invocação usando nosso argumento de procedimento. A seção do manual do PG chamada "Executando Comandos Dinâmicos " explicaEXECUTE
em detalhes.- A declaração do argumento de procedimento
user
devem ser aspas duplas. Aspas duplas forçam-no a ser interpretado como um identificador.
Depois de definir a função assim, você pode chamá-la usando variáveis PSQL interpoladas. Aqui está um esboço.
- Execute
psql --variable user="'whoever'" --file=myscript.sql
. Aspas simples são obrigatórias ao redor do nome de usuário! - Em myscript.sql, defina a função como acima.
- Em myscript.sql, coloque
select foo(:user);
. É aqui que contamos com as aspas simples que colocamos no valor deuser
.
Embora isso pareça funcionar, parece-me bastante esquisito. Eu pensei
SET
variáveis foram destinadas à configuração de tempo de execução. Carregando dados em SET
parece estranho. Editar :aqui está uma razão concreta para não use
SET
variáveis. Da página de manual:"Essas atribuições são feitas durante um estágio muito inicial da inicialização, portanto, as variáveis reservadas para fins internos podem ser substituídas posteriormente." Se o Postgres decidiu usar uma variável chamada user
(ou o que você escolher), pode substituir seu argumento de script por algo que você nunca quis. Na verdade, o psql já aceita USER
para si mesmo -- isso só funciona porque SET
é sensível a maiúsculas e minúsculas. Isso quase quebrou as coisas desde o início!