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

libpq . का उपयोग करके तालिका में फ़्लोटिंग पॉइंट नंबर डालना

आपके कोड में दो त्रुटियां हैं:

  • आप बाइनरी डेटा भेजने की कोशिश कर रहे हैं, लेकिन आप PQexecParams . को नहीं बताते हैं यह किस प्रकार का है।

    यह काम नहीं कर सकता। प्रकार की जानकारी के अभाव में, PostgreSQL unknown . प्रकार का उपयोग करेगा और इसे स्ट्रिंग के रूप में मानें। इसका मतलब है कि आपका बाइनरी प्रतिनिधित्व float8in . पर फीड किया जाएगा फ़ंक्शन जो स्ट्रिंग्स को डबल सटीक मानों में परिवर्तित करता है, जो बुरी तरह विफल हो जाएगा। आप शायद यही देख रहे हैं।

    आपको चौथे पैरामीटर का उपयोग Oid[] . के साथ करना होगा जिसमें 701 (या FLOAT8OID . है) यदि आप इसके बजाय PostgreSQL के #define . का उपयोग करना चाहते हैं , लेकिन आपको #include <postgres.h> और <catalog/pg_type.h> उसके लिए)।

  • आप गलती से मान लेते हैं कि PostgreSQL का double precision . का द्विआधारी प्रतिनिधित्व है प्रकार double . के लिए बाइनरी प्रारूप है आपके क्लाइंट मशीन पर उपयोग में है।

    यदि आपका प्रोग्राम big-endian पर चल रहा है, तो यह गलती से काम कर सकता है। मशीन, चूंकि आजकल लगभग हर आर्किटेक्चर IEEE फ़्लोटिंग पॉइंट नंबर का उपयोग करता है ।

    यदि आप स्रोत कोड पढ़ते हैं, तो आप पाएंगे कि PostgreSQL का ओवर-द-वायर बाइनरी प्रारूप pq_sendfloat8 में परिभाषित है। में src/backend/libpq/pqformat.c , जो pq_sendint64 . को कॉल करता है , जो 8-बाइट मान को नेटवर्क बाइट क्रम में परिवर्तित करता है (जो कि बड़े-एंडियन प्रतिनिधित्व के समान है)।

तो आपको इसके समान एक रूपांतरण फ़ंक्शन परिभाषित करना होगा:

static void to_nbo(double in, double *out) {
    uint64_t *i = (uint64_t *)&in;
    uint32_t *r = (uint32_t *)out;

    /* convert input to network byte order */
    r[0] = htonl((uint32_t)((*i) >> 32));
    r[1] = htonl((uint32_t)*i);
}

तब आपका कोड इस तरह दिख सकता है:

Oid types[1];
double converted;

...

types[0] = FLOAT8OID;
to_nbo(value, &converted);
values[0] = (char *)&converted;

लेकिन स्पष्ट रूप से, टेक्स्ट प्रस्तुतिकरण का उपयोग करना बहुत आसान होगा। इससे आपका कोड PostgreSQL इंटर्नल से स्वतंत्र हो जाएगा और शायद इतना धीमा नहीं होगा।

यह ऐसा नहीं दिखता है, लेकिन अगर double precision मान किसी PostgreSQL तालिका से कहीं और खींचे जाते हैं, आप extra_float_digits = 3 ताकि आपको गारंटी दी जाए कि जब मान उनके स्ट्रिंग प्रतिनिधित्व में परिवर्तित हो जाते हैं तो कोई भी सटीकता न खोएं..




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. OR-ed शर्तों से युक्त उन्नत अनुक्रमण (pgsql)

  2. PostgreSQL में एक तारीख से महीना निकालें

  3. बड़े पैमाने पर टेबल पर अपडेट क्वेरी को कैसे तेज करें

  4. पोस्टग्रेज में जेनरेटेड वैल्यू

  5. PostgreSQL में 50M+ पंक्ति तालिका पर कुल क्वेरी