PostgreSQL
 sql >> Teknologi Basis Data >  >> RDS >> PostgreSQL

Memasukkan angka floating point dalam tabel menggunakan libpq

Ada dua kesalahan dalam kode Anda:

  • Anda mencoba mengirim data biner, tetapi Anda tidak memberi tahu PQexecParams jenis apa itu.

    Itu tidak bisa bekerja. Kurangnya informasi jenis, PostgreSQL akan menggunakan jenis unknown dan memperlakukannya sebagai string. Itu berarti representasi biner Anda akan diumpankan ke float8in fungsi yang mengubah string menjadi nilai presisi ganda, yang akan gagal total. Ini mungkin yang Anda amati.

    Anda harus menggunakan parameter keempat dengan Oid[] yang berisi 701 (atau FLOAT8OID jika Anda lebih suka menggunakan #define PostgreSQL , tetapi Anda harus #include <postgres.h> dan <catalog/pg_type.h> untuk itu).

  • Anda keliru berasumsi bahwa representasi biner PostgreSQL dari double precision type adalah format biner untuk double sedang digunakan di mesin klien Anda.

    Ini mungkin tidak sengaja bekerja jika program Anda berjalan pada big-endian mesin, karena hampir setiap arsitektur saat ini menggunakan nomor floating point IEEE .

    Jika Anda membaca kode sumber, Anda akan menemukan bahwa format biner over-the-wire PostgreSQL didefinisikan dalam pq_sendfloat8 di src/backend/libpq/pqformat.c , yang memanggil pq_sendint64 , yang mengubah nilai 8-byte menjadi urutan byte jaringan (yang sama dengan representasi big-endian).

Jadi, Anda harus mendefinisikan fungsi konversi yang mirip dengan ini:

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);
}

Maka kode Anda akan terlihat seperti ini:

Oid types[1];
double converted;

...

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

Tapi terus terang, akan jauh lebih mudah menggunakan representasi teks. Itu akan membuat kode Anda independen dari internal PostgreSQL dan mungkin tidak jauh lebih lambat.

Tidak terlihat seperti itu, tetapi jika double precision nilai ditarik dari tabel PostgreSQL di tempat lain, Anda dapat mengatur extra_float_digits = 3 sehingga Anda dijamin tidak akan kehilangan presisi saat nilai dikonversi ke representasi string..




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. NULL vs. `infinity` dalam jenis rentang PostgreSQL

  2. PHP tidak memuat php_pgsql.dll di Windows

  3. PostgreSQL bagaimana cara membuat salinan database atau skema?

  4. Membuat tablespace di postgresql

  5. Status SQL Postgres:22P02