Псевдоним для имени функции или процедуры - PullRequest
2 голосов
/ 29 января 2020

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

PL / pg SQL имя столбца совпадает с именем переменной

Есть ли способ определить псевдоним для имени функции или процедуры, который будет использоваться внутри его тела?

Текущий код:

CREATE OR REPLACE PROCEDURE dbo.PR_DeleteCrazyNamedItemByCrazyNamedID(in NamedID UUID)
  LANGUAGE plpgsql AS
$BODY$
DECLARE
BEGIN
    Delete from dbo.Table t where PR_DeleteCrazyNamedItemByCrazyNamedID.NamedID = t.NamedID;
...

Желаемый код:

CREATE OR REPLACE PROCEDURE dbo.PR_DeleteCrazyNamedItemByCrazyNamedID(in NamedID UUID) as proc
  LANGUAGE plpgsql AS
$BODY$
DECLARE
BEGIN
    Delete from dbo.Table t where proc.NamedID = t.NamedID;
...

1 Ответ

4 голосов
/ 30 января 2020

Не напрямую. Кажется, что имя функции отображается как запись, содержащая входные параметры внутри тела функции, но оно не доступно для ALIAS, как предложено в моего ссылочного ответа , потому что оно фактически служит внешним метка . Руководство:

Примечание

На самом деле существует скрытый «внешний блок», окружающий тело любой функции PL / pg SQL. Этот блок предоставляет объявления параметров функции (если есть), а также некоторые специальные переменные, такие как FOUND (см. Раздел 42.5.5 ). Внешний блок помечен именем функции, что означает, что параметры и специальные переменные могут быть дополнены именем функции.

Но вы можете объединить ALIAS для параметров функции с меткой внешнего блока (один уровень вложенности ниже встроенного внешнего блока, помеченного именем функции), например так:

Общий пример с функцией:

CREATE OR REPLACE FUNCTION weird_procedure_name(named_id int)
  RETURNS TABLE (referenced_how text, input_value int) LANGUAGE plpgsql AS
$func$
<< proc >>  -- outer label!
DECLARE
   named_id ALIAS FOR named_id; -- sic!
BEGIN
   RETURN QUERY VALUES
     ('weird_procedure_name.named_id', weird_procedure_name.named_id)
   , ('proc.named_id', proc.named_id)
   , ('named_id', named_id)
   ;
END
$func$;
SELECT * FROM  weird_procedure_name(666);
referenced_how                | input_value
:---------------------------- | ----------:
weird_procedure_name.named_id |         666
proc.named_id                 |         666
named_id                      |         666

db <> Fiddle здесь

named_id ALIAS FOR named_id; кажется бессмысленным шумом, но теперь входной параметр доступен через метку блока - эффективно выполняет то, что вы просите. (При этом вы могли бы выбрать другое имя.)
И я бы, конечно, добавил комментарий к коду, объясняющий, зачем нужны метка и псевдоним, чтобы у следующего умного разработчика не возникло соблазна удалить либо.

Применительно к вашему примеру :

CREATE OR REPLACE PROCEDURE PR_DeleteCrazyNamedItemByCrazyNamedID(in NamedID UUID)
  LANGUAGE plpgsql AS
$BODY$
<< proc >>  -- !
DECLARE
   NamedID ALIAS FOR NamedID; -- sic!
BEGIN
   DELETE FROM dbo.tbl t WHERE t.NamedID = proc.NamedID;  -- what you wanted !
END
$BODY$;

Я все равно предпочел бы работать с уникальными именами параметров для начала, поэтому никакой квалификации вообще не требуется. Мне нравится ставить перед всеми именами параметров префикс подчеркивания (например: _named_id) - и никогда не делать то же самое для других имен объектов.

...