Postgresql
函式參數與使用 USING 子句的 JOIN 結果之間的命名衝突
鑑於目前 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');
db<>fiddle here(也來自上一個問題)。
我用 a 寫了
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) LANGUAGE plpgsql 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$;
大膽強調突出問題。我不能
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.
我知道我可以使用不同的名稱或子查詢或使用其他函式。但我想知道是否有辦法引用該列。我不能使用表限定。人們會認為應該有一種方法。
有沒有?
根據文件PL/pgSQL Under the Hood,您可以在創建函式之前或在函式定義開始時使用配置參數**
plpgsql.variable_conflict
**,聲明您希望如何解決此類衝突。3 種可能的設置是
error
(預設)use_variable
和use_column
:CREATE OR REPLACE FUNCTION f_merge_foobar() RETURNS TABLE(ts int, foo text, bar text) LANGUAGE plpgsql 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$;