2012-09-21 23 views
9

Tôi đang làm việc với API PostgreSQL C, libpq. Tôi cần để có thể chuyển đổi các giá trị trong một PGresult* thành các kiểu dữ liệu tương đương của chúng trong Ruby. Tôi hiện đang chỉ chọn tất cả các dữ liệu và sử dụng PQgetvalue(), mang lại cho tôi một char* mà tôi có thể chuyển đổi thành một chuỗi ruby. Thật dễ dàng. Nhưng có bất kỳ ví dụ nào mà ai đó có thể chia sẻ thực hiện chuyển đổi loại từ char* thành, ví dụ: int, float hoặc double, theo OID trả về PQftype()?Loại chuyển đổi. Tôi phải làm gì với giá trị OID PostgreSQL trong libpq trong C?

Thực ra, trong ngắn hạn, tôi không biết cách diễn giải OID và the documentation dường như không đưa ra bất kỳ gợi ý nào. Tôi đã tìm thấy this page, nhưng điều đó không giúp hiểu cách sử dụng OID này để thực hiện chuyển đổi loại trong API C. Tôi đoán có một danh sách các hằng số ở đâu đó tôi có thể tạo ra một câu lệnh chuyển đổi lớn từ đâu?

Trả lời

3

Để có được loại tên từ một OID, chỉ cần bỏ nó vào regtype:

SELECT 700::oid::regtype -- real 

Để có được loại bất kỳ cột (hoặc biến trong plpgsql), sử dụng pg_typeof():

SELECT pg_typeof(1::real) -- real 

Cung cấp cho bạn câu trả lời của loại regtypedisplayedtext trong psql hoặc pgAdmin. Bạn có thể bỏ nó vào text một cách rõ ràng nếu cần thiết:

SELECT pg_typeof(1::real)::text -- real 

Ngoài ra còn có này "danh sách lớn", vulgo Danh mục bảng pg_type, nơi các loại được đăng ký. Điều này có thể lớn, có một peek:

SELECT * from pg_type LIMIT 10; 

More info in the excellent manual.

+1

Cảm ơn, mặc dù bạn có biết cách nào để có được điều này từ API C thay vì xoay vòng tới máy chủ cho mỗi cột trong mọi kết quả không? Tôi chỉ quan tâm đến các loại lõi, không phải loại người dùng. – d11wtq

+0

Bạn có thể có Postgres gửi thông tin này với mọi kết quả, chỉ cần thêm các mục SELECT - mặc dù nó sẽ là dự phòng (mỗi hàng). Tôi không quen thuộc với API C. –

+0

Không có phim truyền hình. Cảm ơn bạn đã giúp đỡ. Tôi đang triển khai thư viện ứng dụng, do đó, không muốn sửa đổi truy vấn của người dùng hoặc gửi yêu cầu bổ sung quá mức đến máy chủ. Tôi nghĩ rằng tôi đã tìm thấy nó bây giờ, trên thực tế, trong catalog/pg_type.h :) – d11wtq

11

Tôi tìm thấy câu trả lời sau khi yêu cầu này. Về cơ bản có một tập tin gọi là catalog/pg_type.h, cùng với libpq-fe.h và postgres.h. Bạn cần phải bao gồm sau bao gồm libpq-fe.h và postgres.h, sau đó bạn có thể truy cập vào các định nghĩa như TEXTOID, BOOLOID, INT4OID, vv

#include <stdio.h> 
#include <postgres.h> 
#include <libpq-fe.h> 
#include <catalog/pg_type.h> 

// ... snip ... 

if (PQgetisnull(result, row, col)) { 
    // value is NULL, nothing more to do 
} else { 
    char * value = PQgetvalue(result, row, col); 
    int length = PQgetlength(result, row, col); 

    switch (PQftype(result, col)) { 
    case INT2OID: 
    case INT4OID: 
    case INT8OID: 
     // process value as an integer 
     break; 

    default: 
     // just default to a text representation 
    } 
} 

Bạn cần phải nhìn vào tất cả các OIDs trong pg_type.h để thực sự có một danh sách mở rộng hoặc chỉ kiểm tra những gì bạn nhận được khi thực hiện các truy vấn loại cơ bản SELECT 't'::boolean và chỉ tạo công tắc khi bạn cần loại hỗ trợ mới.

+2

Các tiêu đề này là một phần của mã máy chủ bưu chính thay vì mã máy khách libpq. Các giá trị có thay đổi giữa các bản phát hành postgres không? – KayEss

Các vấn đề liên quan