PostgreSQL
 sql >> डेटाबेस >  >> RDS >> PostgreSQL

पीएल/पीजीएसक्यूएल में गतिशील रूप से प्रश्नों को निष्पादित करना

सिस्टम आँकड़े

अपना खुद का रोल करने से पहले, सिस्टम टेबल पर एक नज़र डालें pg_statistic या देखें pg_stats :

इसमें पहले से ही कुछ आँकड़े हो सकते हैं जिनकी आप गणना करने वाले हैं। यह ANALYZE . से भरा हुआ है , ताकि आप जाँचने से पहले उसे नई (या किसी भी) तालिका के लिए चला सकें।

-- ANALYZE tbl;  -- optionally, to init / refresh
SELECT * FROM pg_stats
WHERE tablename = 'tbl'
AND   schemaname = 'public';

सामान्य गतिशील plpgsql फ़ंक्शन

आप किसी तालिका में प्रत्येक स्तंभ के लिए न्यूनतम मान वापस करना चाहते हैं . यह एक तुच्छ कार्य नहीं है, क्योंकि एक फ़ंक्शन (सामान्य रूप से SQL की तरह) निर्माण समय पर रिटर्न प्रकार जानने की मांग करता है - या कम से कम कॉल समय पर पॉलिमॉर्फिक डेटा प्रकारों की सहायता से।

यह फ़ंक्शन स्वचालित रूप से और सुरक्षित रूप से सब कुछ करता है। किसी भी . के लिए काम करता है तालिका, जब तक कुल कार्य min() प्रत्येक कॉलम के लिए अनुमति है। लेकिन आपको जरूरत PL/pgSQL के आसपास अपना रास्ता जानने के लिए।

CREATE OR REPLACE FUNCTION f_min_of(_tbl anyelement)
  RETURNS SETOF anyelement
  LANGUAGE plpgsql AS
$func$
BEGIN
RETURN QUERY EXECUTE (
   SELECT format('SELECT (t::%2$s).* FROM (SELECT min(%1$s) FROM %2$s) t'
                , string_agg(quote_ident(attname), '), min(' ORDER BY attnum)
                , pg_typeof(_tbl)::text)
   FROM   pg_attribute
   WHERE  attrelid = pg_typeof(_tbl)::text::regclass
   AND    NOT attisdropped  -- no dropped (dead) columns
   AND    attnum > 0        -- no system columns
   );
END
$func$;

कॉल करें (महत्वपूर्ण!):

SELECT * FROM f_min_of(NULL::tbl);  -- tbl being the table name

db<>fiddle यहां
पुराना sqlfiddle

आपको इन अवधारणाओं को समझने की जरूरत है:

  • plpgsql में डायनेमिक SQL EXECUTE . के साथ
  • बहुरूपी प्रकार
  • पोस्टग्रेज में पंक्ति प्रकार और तालिका प्रकार
  • एसक्यूएल इंजेक्शन से बचाव कैसे करें
  • कुल कार्य
  • सिस्टम कैटलॉग

विस्तृत विवरण के साथ संबंधित उत्तर:

बेमेल प्रकार के साथ विशेष कठिनाई

मैं प्रत्येक मौजूदा तालिका के लिए एक पंक्ति प्रकार को परिभाषित करने वाले पोस्टग्रेज का लाभ उठा रहा हूं। बहुरूपी प्रकारों की अवधारणा का उपयोग करके मैं एक . बनाने में सक्षम हूं फ़ंक्शन जो किसी भी तालिका के लिए काम करता है।

हालांकि, कुछ समग्र कार्य अंतर्निहित कॉलम की तुलना में संबंधित लेकिन विभिन्न डेटा प्रकार लौटाते हैं। उदाहरण के लिए, min(varchar_column) text लौटाता है , जो बिट-संगत है, लेकिन नहीं बिल्कुल एक ही डेटा प्रकार। पीएल/पीजीएसक्यूएल फ़ंक्शन यहां कमजोर स्थान रखते हैं और डेटा प्रकारों पर जोर देते हैं बिल्कुल जैसा कि RETURNS में घोषित किया गया है खंड। कास्ट करने का कोई प्रयास नहीं, यहां तक ​​​​कि निहित कास्ट भी नहीं, असाइनमेंट कास्ट की बात नहीं करना।

इसमें सुधार किया जाना चाहिए। पोस्टग्रेज 9.3 के साथ परीक्षण किया गया। 9.4 के साथ पुन:परीक्षण नहीं किया, लेकिन मुझे पूरा यकीन है, इस क्षेत्र में कुछ भी नहीं बदला है।

यहीं पर यह निर्माण समाधान . के रूप में आता है :

SELECT (t::tbl).* FROM (SELECT ... FROM tbl) t;

पूरी पंक्ति को अंतर्निहित तालिका के पंक्ति प्रकार में कास्ट करके स्पष्ट रूप से हम असाइनमेंट कास्ट को प्रत्येक कॉलम के लिए मूल डेटा प्रकार प्राप्त करने के लिए बाध्य करते हैं।

यह कुछ समग्र कार्य के लिए विफल हो सकता है। sum() रिटर्न numeric एक sum(bigint_column) . के लिए आधार डेटा प्रकार से अधिक बहने वाली राशि के लिए समायोजित करने के लिए। bigint . पर वापस कास्ट किया जा रहा है विफल हो सकता है ...



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. PostgreSQL पंक्तियों के माध्यम से पुनरावृति और कस्टम दूरी-फ़ंक्शन का उपयोग करके निकटतम मिलान खोजने के लिए

  2. Postgres . में Concat पंक्तियाँ

  3. Sail.js प्रारंभ पर एकाधिक कनेक्शन

  4. बहु-पंक्ति क्वेरी के लिए psql की \ copy का उपयोग करें

  5. PostgreSQL:'मिनट के हिसाब से' क्वेरी के लिए पंक्तियों की गिनती चल रही है