PostgreSQL
 sql >> Base de Dados >  >> RDS >> PostgreSQL

Existe alguma sintaxe de escape para a variável psql dentro das funções do PostgreSQL?


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:
  1. EXECUTE gera um GRANT apropriado em cada invocação usando nosso argumento de procedimento. A seção do manual do PG chamada "Executando Comandos Dinâmicos " explica EXECUTE em detalhes.
  2. 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.
  1. Execute psql --variable user="'whoever'" --file=myscript.sql . Aspas simples são obrigatórias ao redor do nome de usuário!
  2. Em myscript.sql, defina a função como acima.
  3. Em myscript.sql, coloque select foo(:user); . É aqui que contamos com as aspas simples que colocamos no valor de user .

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!