फ़ंक्शन पैरामीटर के बीच नामकरण संघर्ष और USING क्लॉज़ के साथ JOIN के परिणाम


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 फिडेल भी है ।

मैंने संदर्भित प्रश्न के उद्देश्य को प्राप्त करने के लिए एक के 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

डॉक्स पीएल / पीजीसीक्यूडी के तहत हुड के अनुसार , आप कॉन्फ़िगरेशन पैरामीटर का उपयोग कर सकते हैं plpgsql.variable_conflict, या तो फ़ंक्शन बनाने से पहले या फ़ंक्शन परिभाषा की शुरुआत में, यह घोषणा करते हुए कि आप इस तरह के संघर्षों को कैसे हल करना चाहते हैं error( 3 संभावित मान हैं) (डिफ़ॉल्ट ), 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
उत्तम। मुझे नागवार उत्तेजना हो रही थी, मुझे कुछ याद आ रहा था। मैं वास्तव में अतीत में इस्तेमाल किया है कि याद है। धन्यवाद!
इरविन ब्रान्डस्टेट्टर
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.