Đặt tên xung đột giữa tham số hàm và kết quả của THAM GIA với mệnh đề USING


16

Đưa ra thiết lập này trong Postgres hiện tại 9.4 ( từ câu hỏi liên quan này ):

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');

Ngoài ra còn có SQL Fiddle từ câu hỏi trước.

Tôi đã viết một SELECTvới một FULL JOINđể đạt được mục tiêu của câu hỏi được tham khảo. Giản thể:

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

Theo thông số kỹ thuật, cách chính xác để giải quyết cột tslà không có đủ điều kiện bảng. Một trong hai giá trị đầu vào ( f.tshoặc b.ts) có thể là NULL. Các USINGkhoản tạo ra một chút của một trường hợp kỳ lạ: giới thiệu một cột "đầu vào" đó không phải là thực sự hiện diện trong đầu vào. Cho đến nay thanh lịch.

Tôi đặt cái này trong hàm plpgsql. Để thuận tiện (hoặc yêu cầu) tôi muốn các tên cột giống nhau cho kết quả của hàm bảng. Vì vậy, chúng ta phải tránh xung đột đặt tên giữa các tên cột giống nhau và các tham số hàm. Tốt nhất nên tránh bằng cách chọn các tên khác nhau, nhưng ở đây chúng tôi là:

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;

Nhấn mạnh đậm để làm nổi bật vấn đề . Tôi không thể sử dụng tsmà không có trình độ bảng như trước đây, bởi vì plpgsql sẽ đưa ra một ngoại lệ (không thực sự cần thiết, nhưng có lẽ hữu ích trong hầu hết các trường hợp):

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.

Tôi biết tôi có thể sử dụng các tên khác nhau hoặc truy vấn con hoặc sử dụng chức năng khác. Nhưng tôi tự hỏi nếu có một cách để tham khảo cột. Tôi không thể sử dụng bảng chất lượng. Người ta sẽ nghĩ nên có một cách.
Lanhung?

Câu trả lời:


18

Theo tài liệu PL / pgSQL Under the Hood , bạn có thể sử dụng tham số cấu hình plpgsql.variable_conflict, trước khi tạo hàm hoặc khi bắt đầu định nghĩa hàm, khai báo cách bạn muốn giải quyết các xung đột đó (3 giá trị có thể là error(mặc định ) use_variableuse_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
Hoàn hảo. Tôi có cảm giác dai dẳng tôi đang thiếu thứ gì đó. Tôi thực sự nhớ rằng đã sử dụng nó trong quá khứ. Cảm ơn bạn!
Erwin Brandstetter
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.