PostgreSQL
 sql >> база данни >  >> RDS >> PostgreSQL

Има ли екраниращ синтаксис за psql променлива във функциите на PostgreSQL?

PSQL SET променливите не се интерполират вътре в низове в доларови кавички. Не знам това със сигурност, но мисля, че няма спасение или друг трик за включване на SET променлива интерполация там.

Някой може да си помисли, че можете да поставите :user без кавички между два котирани в долари участъка на PL/pgSQL, за да получите желания ефект. Но това изглежда не работи... Мисля, че синтаксисът изисква единичен низ, а не израз, обединяващ низове. Може да греша.

Както и да е, това няма значение. Има друг подход (както отбеляза Паско):напишете съхранената процедура, за да приеме PL/pgSQL аргумент. Ето как би изглеждало това.

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;

Бележки за тази функция:

  1. EXECUTE генерира подходящо GRANT при всяко извикване, използвайки аргумента на нашата процедура. Ръководният раздел на PG, наречен "Изпълнение на динамични команди " обяснява EXECUTE подробно.
  2. Декларацията на аргумента на процедурата user трябва да бъде в двойни кавички. Двойните кавички принуждават да се тълкува като идентификатор.

След като дефинирате функцията по този начин, можете да я извикате с помощта на интерполирани PSQL променливи. Ето схема.

  1. Изпълнете psql --variable user="'whoever'" --file=myscript.sql . Около потребителското име са задължителни единични кавички!
  2. В myscript.sql дефинирайте функция като по-горе.
  3. В myscript.sql поставете select foo(:user); . Тук разчитаме на онези единични кавички, които поставяме в стойността на user .

Въпреки че това изглежда работи, ми се струва доста странно. Помислих си SET променливите бяха предназначени за конфигурация по време на изпълнение. Пренасяне на данни в SET изглежда странно.

Редактиране :ето конкретна причина не използвайте SET променливи. От страницата на ръководството:„Тези присвоявания се извършват по време на много ранен етап на стартиране, така че променливите, запазени за вътрешни цели, може да бъдат презаписани по-късно.“ Ако Postgres реши да използва променлива с име user (или каквото и да изберете), може да замени аргумента на скрипта ви с нещо, което никога не сте възнамерявали. Всъщност psql вече приема USER за себе си -- това работи само защото SET е чувствителен към главни и малки букви. Това почти провали нещата от самото начало!



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. docker-compose rails rake db:reset е неуспешно, не може да премахне текущо отворената база данни

  2. Ролята не съществува и не може да се създаде база данни, когато се използва PostgreSQL

  3. Преброяване на групирани пропуски във времето за времеви диапазон

  4. heroku run rake db:migrate грешка

  5. PG gem няма да се инсталира в приложението Rails:Gem::Ext::BuildError:ГРЕШКА:Неуспешно изграждане на естествено разширение за gem