sql >> Databáze >  >> RDS >> PostgreSQL

Existuje nějaká escapující syntaxe pro proměnnou psql uvnitř funkcí PostgreSQL?

PSQL SET proměnné nejsou interpolovány uvnitř řetězců v dolarech. Nevím to jistě, ale myslím, že neexistuje žádný únik nebo jiný trik, jak zapnout SET proměnná interpolace.

Někdo by si mohl myslet, že byste mohli zaklínit neuvedený :user mezi dvěma dolarovými kotovanými úseky PL/pgSQL, abyste dosáhli požadovaného efektu. Ale zdá se, že to nefunguje... Myslím, že syntaxe vyžaduje jeden řetězec a ne výraz spojující řetězce. V tom se můžete mýlit.

Každopádně na tom nezáleží. Existuje další přístup (jak poznamenal Pasco):napište uloženou proceduru tak, aby přijala argument PL/pgSQL. Zde je návod, jak by to vypadalo.

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;

Poznámky k této funkci:

  1. EXECUTE vygeneruje vhodný GRANT při každém vyvolání pomocí našeho argumentu procedury. Část příručky PG s názvem "Provádění dynamických příkazů “ vysvětluje EXECUTE podrobně.
  2. Argument deklarace procedury user musí být uvozováno dvakrát. Dvojité uvozovky nutí, aby byl interpretován jako identifikátor.

Jakmile funkci definujete takto, můžete ji volat pomocí interpolovaných proměnných PSQL. Zde je přehled.

  1. Spusťte psql --variable user="'whoever'" --file=myscript.sql . U uživatelského jména jsou povinné jednoduché uvozovky!
  2. V souboru myscript.sql definujte funkci jako výše.
  3. Do souboru myscript.sql vložte select foo(:user); . Zde se spoléháme na ty jednoduché uvozovky, které vkládáme do hodnoty user .

I když se zdá, že to funguje, připadá mi to spíše jako veverka. Myslel jsem SET proměnné byly určeny pro konfiguraci za běhu. Přenášení dat v SET vypadá divně.

Upravit :zde je konkrétní důvod, proč ne použijte SET proměnné. Z manuálové stránky:"Tato přiřazení se provádí během velmi rané fáze spouštění, takže proměnné vyhrazené pro interní účely mohou být později přepsány." Pokud se Postgres rozhodl použít proměnnou s názvem user (nebo cokoli, co si vyberete), může to přepsat váš argument skriptu něčím, co jste nikdy nezamýšleli. Ve skutečnosti psql již bere USER pro sebe -- to funguje pouze proto, že SET rozlišuje velká a malá písmena. Tohle málem rozbilo věci od začátku!



  1. Reprodukujte com.mysql.jdbc.exceptions.jdbc4.CommunicationsException s nastavením Spring, hibernate a C3P0

  2. Jak mohu ručně vložit soubor .png nebo .jpeg do sloupce bytea v PostgreSQL?

  3. Získejte velikost všech tabulek v databázi

  4. Co je nového v ProxySQL 2.0