PostgreSQL
 sql >> Baza danych >  >> RDS >> PostgreSQL

Czy istnieje jakaś składnia ucieczki dla zmiennej psql w funkcjach PostgreSQL?

PSQL SET zmienne nie są interpolowane wewnątrz ciągów w cudzysłowie. Nie wiem tego na pewno, ale myślę, że nie ma ucieczki ani innych sztuczek, aby włączyć SET tam zmienna interpolacja.

Można by pomyśleć, że mógłbyś zaklinować nie cytowany :user między dwoma odcinkami PL/pgSQL cytowanymi w dolarach, aby uzyskać pożądany efekt. Ale to nie działa... Myślę, że składnia wymaga pojedynczego ciągu, a nie wyrażenia łączącego ciągi. Może się co do tego mylić.

W każdym razie to nie ma znaczenia. Jest inne podejście (jak zauważył Pasco):napisz procedurę składowaną, aby akceptowała argument PL/pgSQL. Oto, jak by to wyglądało.

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;

Uwagi dotyczące tej funkcji:

  1. EXECUTE generuje odpowiedni GRANT przy każdym wywołaniu przy użyciu naszego argumentu procedury. Sekcja podręcznika PG o nazwie "Wykonywanie dynamicznych poleceń " wyjaśnia EXECUTE szczegółowo.
  2. Deklaracja argumentu procedury user musi być w cudzysłowie. Podwójne cudzysłowy wymuszają interpretację jako identyfikator.

Gdy zdefiniujesz funkcję w ten sposób, możesz ją wywołać za pomocą interpolowanych zmiennych PSQL. Oto zarys.

  1. Uruchom psql --variable user="'whoever'" --file=myscript.sql . Wokół nazwy użytkownika wymagane są pojedyncze cudzysłowy!
  2. W myscript.sql zdefiniuj funkcję jak powyżej.
  3. W myscript.sql umieść select foo(:user); . Tutaj polegamy na tych pojedynczych cudzysłowach, które umieszczamy w wartości user .

Chociaż wydaje się to działać, wydaje mi się, że jest to dość dziwaczne. Myślałem, że SET zmienne były przeznaczone do konfiguracji środowiska uruchomieniowego. Noszenie danych w SET wydaje się dziwne.

Edytuj :oto konkretny powód, dla którego nie użyj SET zmienne. Ze strony podręcznika:„Te przypisania są wykonywane na bardzo wczesnym etapie uruchamiania, więc zmienne zarezerwowane do celów wewnętrznych mogą zostać później nadpisane”. Jeśli Postgres zdecydował się użyć zmiennej o nazwie user (lub cokolwiek wybierzesz), może nadpisać argument skryptu czymś, czego nigdy nie zamierzałeś. W rzeczywistości psql już przyjmuje USER dla siebie -- to działa tylko dlatego, że SET uwzględnia wielkość liter. To prawie zepsuło wszystko od samego początku!



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Jak mogę sprawdzić, czy kolumna istnieje w tabeli za pomocą instrukcji SQL?

  2. Jak obliczyć różnicę DATY w PostgreSQL?

  3. Nie możesz wstawić nowego wiersza do tabeli bazy danych postgres?

  4. Jak utworzyć widok SQL za pomocą SQLAlchemy?

  5. błąd :podzapytanie musi zwrócić tylko jedną kolumnę