Іменування конфлікту між параметром функції та результатом JOIN із пунктом USING


17

Враховуючи цю установку в поточному Postgres 9.4 ( з цього пов'язаного питання ):

CREATE TABLE foo (ts, foo) AS 
VALUES (1, 'A')  -- int, text
     , (7, 'B');

CREATE TABLE bar (ts, bar) AS
VALUES (3, 'C')
     , (5, 'D')
     , (9, 'E');

Також є SQL Fiddle з попереднього питання.

Я написав SELECTз FULL JOINдля досягнення мети посилального питання. Спрощено:

SELECT ts, f.foo, b.bar
FROM   foo f
FULL   JOIN bar b USING (ts);

Відповідно до специфікацій, правильний спосіб звернення до стовпця tsне має кваліфікації таблиці. Будь-яке з вхідних значень ( f.tsабо b.ts) може бути NULL. USINGПоложення створює трохи непарний разі: введення стовпця «введення» , який фактично не присутній у вхідних даних. Поки що так елегантно.

Я ставлю це до функції plpgsql. Для зручності (або вимог) я хочу однакові назви стовпців для результату функції таблиці. Тому ми повинні уникати конфлікту між ідентичними іменами стовпців та параметрами функції. Слід уникати найкращих імен, але ось ми:

CREATE OR REPLACE FUNCTION f_merge_foobar()
  RETURNS TABLE(ts int, foo text, bar text) AS
$func$
BEGIN
   FOR ts, foo, bar IN
      SELECT COALESCE(f.ts, b.ts), f.foo, b.bar
      FROM   foo f
      FULL   JOIN bar b USING (ts)
   LOOP
      -- so something
      RETURN NEXT;
   END LOOP;
END
$func$ LANGUAGE plpgsql;

Сміливий акцент, щоб висвітлити проблему . Я не можу використовувати tsбез табличної кваліфікації, як раніше, оскільки plpgsql створить виняток (не суворо необхідний, але, мабуть, корисний у більшості випадків):

ERROR:  column reference "ts" is ambiguous
LINE 1: SELECT ts, f.foo, b.bar
               ^
DETAIL:  It could refer to either a PL/pgSQL variable or a table column.

Я знаю, що я можу використовувати різні імена, підзапит або використовувати іншу функцію. Але мені цікаво, чи є спосіб посилатися на колонку. Я не можу використовувати табличну кваліфікацію. Можна було б подумати, що має бути спосіб.
Є там?

Відповіді:


19

Згідно з документами PL / pgSQL Під кришкою ви можете використовувати параметр конфігурації plpgsql.variable_conflictперед створенням функції або на початку визначення функції, оголосивши, як потрібно вирішувати такі конфлікти (3 можливі значення є error(за замовчуванням ), use_variableі use_column):

CREATE OR REPLACE FUNCTION pg_temp.f_merge_foobar()
  RETURNS TABLE(ts int, foo text, bar text) AS
$func$
#variable_conflict use_column             -- how to resolve conflicts
BEGIN
   FOR ts, foo, bar IN
      SELECT ts, f.foo, b.bar
      FROM   foo f
      FULL   JOIN bar b USING (ts)
   LOOP
      -- do something
      RETURN NEXT;
   END LOOP;
END
$func$ LANGUAGE plpgsql;

1
Ідеально. У мене з'явилося нудне відчуття, що мені щось не вистачало. Я фактично пам'ятаю, як раніше це використовував. Дякую!
Erwin Brandstetter
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.