Ссылка на столбец "id" неоднозначна - она ​​может ссылаться либо на переменную PL / pgSQL, либо на столбец таблицы - PullRequest
0 голосов
/ 08 ноября 2018

У меня есть эта простая тестовая функция в Postgres (в моей test схеме).

CREATE OR REPLACE FUNCTION test.func_001
(
par_id int
)
RETURNS TABLE
(
id int
)

AS
$BODY$
DECLARE

    var_id int;

BEGIN

    update test.item    --- this is a table 
    set 
    id = 4
    WHERE
    id = 44;

return query 
select 1000 as id;

END;
$BODY$
LANGUAGE  plpgsql;

В таблице test.item есть один столбец идентификатора.

Я получаю ошибкуниже при попытке запустить функцию.

Query execution failed

Reason:
SQL Error [42702]: ERROR: column reference "id" is ambiguous
  Detail: It could refer to either a PL/pgSQL variable or a table column.
  Where: PL/pgSQL function test.func_001(integer) line 8 at SQL statement

Эта ошибка кажется странной, означает ли это, что Postgres обнаруживает конфликт / конфликт между столбцом test.item.id и столбцом id из возвращенной таблицы?!Как так?Это не имеет никакого смысла.

Я не могу в это поверить, но я не вижу здесь никаких других идентификаторов.

Заметьте, что если я закомментирую только эту часть.

-- WHERE
-- id = 44;

, тогда внезапно функция будет работать нормально.

Так что, похоже, Postgres путает идентификатор в предложении where с чем-то еще, называемым id?!

С чем?

Это совершенно нелогично и нелогично.

Может кто-нибудь объяснить, пожалуйста?

Ответы [ 2 ]

0 голосов
/ 08 ноября 2018

Предложение FUNCTION fx() RETURNS TABLE(x int, y int, ...) такое же, как FUNCTION(OUT x int, OUT y int) RETURNS SETOF record. Так что в вашем случае есть неявная переменная id, хотя вы не используете ее явно.

Конструкция PostgreSQL позволяет создавать строки без SQL.

CREATE OR REPLACE FUNCTION foo(a int)
RETURNS TABLE(b int, c int) AS $$
BEGIN
  FOR i IN 1..a
  LOOP
    b := i; c := i * 10;
    RETURN NEXT;
  END LOOP;
END;
$$ LANGUAGE plpgsql;

См. следующий документ, пожалуйста.

Существует еще один способ объявить функцию как возвращающую набор, которая заключается в использовании синтаксиса RETURNS TABLE (столбцы). Это эквивалентно использованию одного или нескольких параметров OUT плюс маркировка функции как возвращающей запись SETOF (или, в зависимости от ситуации, SETOF типа отдельного выходного параметра). Эта нотация указана в последних версиях стандарта SQL и поэтому может быть более переносимой, чем использование SETOF.

0 голосов
/ 08 ноября 2018

Существует конфликт имен между переменной id, которая определяется предложением RETURNS TABLE, и столбцом с тем же именем.

Подобные вещи вызывают проблемы на всех языках программирования, только PostgreSQL достаточно хорош, чтобы предупреждать вас, а не делать что-то, что может не соответствовать вашим ожиданиям.

Определите ссылку на столбец следующим образом, чтобы устранить неоднозначность:

WHERE test.item.id = 44
...