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

पीएल/पीजीएसक्यूएल फ़ंक्शन में इंट लिटरल बनाम इंट पैरामीटर के बीच अंतर को समझना

क्यों?

PL/pgSQL SQL क्वेरी जैसे तैयार किए गए कथन को निष्पादित करता है . पैरामीटर प्रतिस्थापन के बारे में मैनुअल:

मानों शब्द पर ध्यान दें . केवल वास्तविक मानों को पैरामीटर किया जा सकता है, लेकिन कीवर्ड, पहचानकर्ता या प्रकार के नाम नहीं। 32 bit(32) में दिखता है मान की तरह, लेकिन डेटा प्रकार का संशोधक आंतरिक रूप से केवल "मान" होता है और इसे पैरामीटरकृत नहीं किया जा सकता है। SQL योजना चरण में डेटा प्रकारों को जानने की मांग करता है, यह निष्पादन चरण की प्रतीक्षा नहीं कर सकता।

आप कर सकते थे गतिशील SQL और EXECUTE . के साथ अपने लक्ष्य को प्राप्त करें . अवधारणा के प्रमाण . के रूप में :

CREATE OR REPLACE FUNCTION lpad_bits(val varbit, sz int = 32, OUT outval varbit) AS
$func$
BEGIN
   EXECUTE format('SELECT $1::bit(%s) >> $2', sz)  -- literal
   USING val, sz - length(val)                     -- values
   INTO outval;
END
$func$  LANGUAGE plpgsql IMMUTABLE;

कॉल करें:

SELECT lpad_bits(b'1001100111000', 32);  

sz . के बीच अंतर पर ध्यान दें शाब्दिक . के रूप में उपयोग किया जा रहा है स्टेटमेंट बनाने के लिए और इसकी दूसरी घटना जहां इसे value . के रूप में उपयोग किया जाता है , जिसे पैरामीटर के रूप में पारित किया जा सकता है।

तेज़ विकल्प

इस विशेष कार्य के लिए एक बेहतर समाधान केवल lpad() . का उपयोग करना है जैसे @Abelisto ने सुझाव दिया :

CREATE OR REPLACE FUNCTION lpad_bits2(val varbit, sz int = 32)
  RETURNS varbit AS
$func$
SELECT lpad(val::text, sz, '0')::varbit;
$func$  LANGUAGE sql IMMUTABLE;

(सादे SQL फ़ंक्शन के रूप में सरल, जो फ़ंक्शन इनलाइनिंग की भी अनुमति देता है बाहरी प्रश्नों के संदर्भ में।)

उपरोक्त फ़ंक्शन से कई गुना तेज। एक छोटी सी खामी:हमें text पर डालना होगा और वापस varbit . पर जाएं . दुर्भाग्य से, lpad() वर्तमान में varbit . के लिए क्रियान्वित नहीं किया गया है . मैनुअल:

overlay() उपलब्ध है, हमारे पास एक सस्ता कार्य हो सकता है:

CREATE OR REPLACE FUNCTION lpad_bits3(val varbit, base varbit = '00000000000000000000000000000000')
  RETURNS varbit AS
$func$
SELECT overlay(base PLACING val FROM bit_length(base) - bit_length(val))
$func$  LANGUAGE sql IMMUTABLE;

अगर आप varbit . के साथ काम कर सकते हैं तो तेज़ शुरू करने के लिए मूल्य। (लाभ (आंशिक रूप से) शून्य है, अगर आपको text cast डालना है करने के लिए varbit वैसे भी।)

कॉल करें:

SELECT lpad_bits3(b'1001100111000', '00000000000000000000000000000000');
SELECT lpad_bits3(b'1001100111000',  repeat('0', 32)::varbit);

हम ओवरलाड . कर सकते हैं base . उत्पन्न करने के लिए एक पूर्णांक लेने वाले प्रकार के साथ फ़ंक्शन स्वयं:

CREATE OR REPLACE FUNCTION lpad_bits3(val varbit, sz int = 32)
  RETURNS varbit AS
$func$
SELECT overlay(repeat('0', sz)::varbit PLACING val FROM sz - bit_length(val))
$func$  LANGUAGE sql IMMUTABLE;

कॉल करें:

SELECT lpad_bits3(b'1001100111000', 32;

संबंधित:



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. DBIx::Class::ResultSet की find_or_create विधि का उपयोग करते समय दौड़ की स्थिति से कैसे बचें?

  2. PostgreSQL में धीमी क्वेरी लॉग को कैसे सक्षम करें

  3. बड़ी मात्रा में डेटा के लिए PostgreSQL को स्केल करना

  4. PostgreSQL ट्रिगर्स को यूजर आईडी पास करना

  5. Docker कंटेनर पर PostgreSQL डेटाबेस से कनेक्ट करें