Определить имена таблиц и столбцов в качестве аргументов в функции plpgsql?

Это должно быть просто, но я делаю первые шаги в функциях Postgres, и я не могу найти ничего, что работает …

Я хотел бы создать функцию, которая будет изменять таблицу и / или столбец, и я не могу найти правильный способ указания моих таблиц и столбцов в качестве аргументов в моей функции.

Что-то вроде:

CREATE OR REPLACE FUNCTION foo(t table) RETURNS void AS $$ BEGIN alter table t add column c1 varchar(20); alter table t add column c2 varchar(20); alter table t add column c3 varchar(20); alter table t add column c4 varchar(20); END; $$ LANGUAGE PLPGSQL; select foo(some_table) 

В другом случае я хотел бы иметь функцию, которая изменяет определенный столбец из определенной таблицы:

 CREATE OR REPLACE FUNCTION foo(t table, c column) RETURNS void AS $$ BEGIN UPDATE t SET c = "This is a test"; END; $$ LANGUAGE PLPGSQL; 

Можно ли это сделать?

Вы должны защищаться от SQL-инъекции всякий раз, когда вы включаете ввод пользователя в код. Это включает имена таблиц и столбцов, поступающие из системных каталогов или из прямого ввода пользователя. Таким образом, вы также предотвращаете тривиальные исключения с нестандартными идентификаторами. Существуют три основных метода:

1. format()

1-й запрос, дезинфицированный:

 CREATE OR REPLACE FUNCTION foo(_t text) RETURNS void AS $func$ BEGIN EXECUTE format(' ALTER TABLE %I ADD COLUMN c1 varchar(20) , ADD COLUMN c2 varchar(20)', _t); END $func$ LANGUAGE plpgsql; 

format() требует Postgres 9.1 или новее. Используйте его с спецификатором формата %I

Имя таблицы может быть неоднозначным. Возможно, вам придется указать имя схемы, чтобы избежать неправильной замены неправильной таблицы. Связанный:

  • INSERT с динамическим именем таблицы в триггерной функции
  • Как влияет на идентификатор идентификатора поиска и «текущая схема»,

Помимо этого: добавление нескольких столбцов с одной командой ALTER TABLE дешевле.

2. regclass

Вы также можете использовать бросок для зарегистрированного classа ( regclass ) для специального случая существующих имен таблиц. Необязательно с учетом схемы. Это немедленно и изящно не работает для имен таблиц, которые не являются действительными и видимыми вызывающему пользователю. 1-й запрос, дезинфицированный с актерским составом:

 CREATE OR REPLACE FUNCTION foo(_t regclass) RETURNS void AS $func$ BEGIN EXECUTE 'ALTER TABLE '|| _t ||' ADD COLUMN c1 varchar(20) , ADD COLUMN c2 varchar(20)'; END $func$ LANGUAGE plpgsql; 

Вызов:

 SELECT foo('table_name'); 

Или:

 SELECT foo('my_schema.table_name'::regclass); 

Кроме того: рассмотрим использование только text вместо varchar(20) .

3. quote_ident()

Второй запрос подвергся дезинфекции:

 CREATE OR REPLACE FUNCTION foo(_t regclass, _c text) RETURNS void AS $func$ BEGIN EXECUTE 'UPDATE '|| _t ||' -- sanitized with regclass SET '|| quote_ident(_c) ||' = ''This is a test'''; END $func$ LANGUAGE plpgsql; 

Для множественных конкатенаций / интерполяций format() является более чистым …

Похожие ответы:

  • Имя таблицы как параметр функции PostgreSQL
  • Функции Postgres и подготовленные запросы

Деликатный случай!

Имейте в виду, что идентификаторы без кавычек не отображаются в нижнем регистре. При использовании в качестве идентификатора в SQL Postgres автоматически применяется к строчке . Но здесь мы передаем строки для динамического SQL. Когда экраны экранируются, как показано, идентификаторы CaMel-case (например, UserS ) будут сохранены путем двойного запуска ( "UserS" ), как и другие нестандартные имена, такие как "name with space" "SELECT" и т. Д. Следовательно, имена чувствительны к регистру в этом контекст.

Мой постоянный совет заключается в том, чтобы использовать юридические идентификаторы нижнего регистра исключительно и никогда не беспокоиться об этом.

Помимо этого: одинарные кавычки для значений, двойные кавычки для идентификаторов .

  • «Срок службы» строкового литерала в C
  • Функция Excel для создания SQL-подобных запросов в данных рабочего листа?
  • strdup () - что он делает в C?
  • Вызвать функцию, названную в строковой переменной в C
  • Могу ли я сделать функцию доступной в каждом controllerе в угловом?
  • jquery - разница между $ .functionName и $ .fn.FunctionName
  • Разрешение перегрузки C ++
  • Синтаксис функции C, типы параметров, объявленные после списка параметров
  • Разница между и * звездочкой
  • Как не членские функции улучшают инкапсуляцию
  • Как изменить реализацию (обход) функции, объявленной извне
  • Давайте будем гением компьютера.