Chọn kiểu dữ liệu của trường trong postgres


165

Làm cách nào để có được kiểu dữ liệu của trường cụ thể từ bảng trong postgres? Ví dụ: tôi có bảng sau, student_details (số nguyên stu_id, stu_name varchar (30), dấu thời gian tham gia);

Trong trường hợp này bằng cách sử dụng tên trường / hoặc bất kỳ cách nào khác, tôi cần lấy kiểu dữ liệu của trường cụ thể. Có khả năng nào không?


1
Cũng đã hỏi và trả lời stackoverflow.com/q/20194806/65458
Piotr Findeisen

Câu trả lời:


173

Bạn có thể nhận các loại dữ liệu từ information_schema (8.4 tài liệu được tham chiếu ở đây, nhưng đây không phải là một tính năng mới):

=# select column_name, data_type from information_schema.columns
-# where table_name = 'config';
    column_name     | data_type 
--------------------+-----------
 id                 | integer
 default_printer_id | integer
 master_host_enable | boolean
(3 rows)

Thật đơn giản và tốt đẹp! Bây giờ tôi có thể thay thế truy vấn hiện tại mà tôi thấy là 310 ký tự (không có tên bảng), tham gia 4 bảng, không nhận biết lược đồ, đắt tiền và cung cấp 'int4' và các loại khác dưới dạng số thay vì số nguyên. Cảm ơn bạn!
một số

2
PostgreSQL cho phép bạn có cùng tên bảng (thậm chí là một bảng giống hệt nhau) trong nhiều lược đồ. Cách mạnh mẽ để viết mệnh đề WHERE xem xét khả năng đó: where table_catalog = ? and table_schema = ? and table_name = ?;Nhưng chế độ xem information_schema này không xem xét rằng DDL có thể đã sử dụng các miền .
Mike Sherrill 'Nhớ lại mèo'

1
Điều này sẽ không cung cấp cho bạn loại mảng, vì vậy nó phải được sử dụng cùng vớipg_typeof
Daria

146

Bạn có thể sử dụng hàm pg_typeof () , cũng hoạt động tốt cho các giá trị tùy ý.

SELECT pg_typeof("stu_id"), pg_typeof(100) from student_details limit 1;

cái này trả về một hàng trên mỗi bản ghi trong bảng. Đừng chạy nó nếu bạn có hàng triệu hồ sơ
Saarang

3
Điều này hoạt động rất đẹp nếu bạn cần xác định loại tính toán. ví dụ, SELECT pg_typeof( date_part( 'year', now() ) ) AS exprcó lẽ khác với những gì bạn mong đợi.
Leo Orientis

điều thông minh ở đây là pg_typeofhoạt động cho các trường xuất phát từ các thủ tục được lưu trữ, mà bảng phụ trợ, nếu nó còn tồn tại, không rõ / không rõ ràng. select state, qstart, pg_typeof(qstart) as ty_qstart from listconn(). information_schema sẽ không giúp nhiều ở đây.
JL Peyret

40

Hãy thử yêu cầu này:

SELECT column_name, data_type FROM information_schema.columns WHERE 
table_name = 'YOUR_TABLE' AND column_name = 'YOUR_FIELD';

4
table_name = 'YOUR_TABLE' AND column_name = 'YOUR_FIELD';
haitham

38

chạy psql -Evà sau đó\d student_details


đơn giản và hữu ích
horoyoi o

11

Nếu bạn thích giải pháp 'Mike Sherrill' nhưng không muốn sử dụng psql, tôi đã sử dụng truy vấn này để lấy thông tin còn thiếu:

select column_name,
case 
    when domain_name is not null then domain_name
    when data_type='character varying' THEN 'varchar('||character_maximum_length||')'
    when data_type='numeric' THEN 'numeric('||numeric_precision||','||numeric_scale||')'
    else data_type
end as myType
from information_schema.columns
where table_name='test'

với kết quả:

column_name |     myType
-------------+-------------------
 test_id     | test_domain
 test_vc     | varchar(15)
 test_n      | numeric(15,3)
 big_n       | bigint
 ip_addr     | inet

8

Các khung nhìn lược đồ thông tin và pg_typeof () trả về thông tin loại không đầy đủ. Trong số các câu trả lời, psqlđưa ra thông tin loại chính xác nhất. (OP có thể không cần thông tin chính xác như vậy, nhưng nên biết những hạn chế.)

create domain test_domain as varchar(15);

create table test (
  test_id test_domain, 
  test_vc varchar(15), 
  test_n numeric(15, 3), 
  big_n bigint,
  ip_addr inet
);

Sử dụng psql\d public.testhiển thị chính xác việc sử dụng kiểu dữ liệu test_domain, độ dài của cột varchar (n) và độ chính xác và tỷ lệ của cột số (p, s).

hộp cát = # \ d công khai.
             Bảng "công khai"
 Cột | Loại | Công cụ sửa đổi
--------- + ----------------------- + -----------
 test_id | tên miền thử nghiệm |
 test_vc | thay đổi ký tự (15) |
 thử nghiệm | số (15,3) |
 big_n | ông lớn |
 ip_addr | inet |

Truy vấn này đối với chế độ xem information_schema hoàn toàn không hiển thị việc sử dụng test_domain. Nó cũng không báo cáo chi tiết về các cột varchar (n) và số (p, s).

select column_name, data_type 
from information_schema.columns 
where table_catalog = 'sandbox'
  and table_schema = 'public'
  and table_name = 'test';
cột_name | loại dữ liệu
------------- + -------------------
 test_id | thay đổi nhân vật
 test_vc | thay đổi nhân vật
 thử nghiệm | số
 big_n | ông lớn
 ip_addr | inet

Bạn thể có được tất cả thông tin đó bằng cách tham gia các khung nhìn information_schema khác hoặc bằng cách truy vấn trực tiếp các bảng hệ thống. psql -Ecó thể giúp với điều đó.

Hàm pg_typeof()hiển thị chính xác việc sử dụng test_domain, nhưng không báo cáo chi tiết về các cột varchar (n) và số (p, s).

select pg_typeof(test_id) as test_id, 
       pg_typeof(test_vc) as test_vc,
       pg_typeof(test_n) as test_n,
       pg_typeof(big_n) as big_n,
       pg_typeof(ip_addr) as ip_addr
from test;
   test_id | test_vc | thử nghiệm | big_n | ip_addr
------------- + ------------------- + --------- + ------ - + ---------
 tên miền thử nghiệm | thay đổi nhân vật | số | ông lớn | inet

4

Có thể kéo kiểu dữ liệu từ information_schemanhưng không thuận tiện (yêu cầu nối nhiều cột với casecâu lệnh). Ngoài ra, người ta có thể sử dụng format_typechức năng tích hợp để làm điều đó, nhưng nó hoạt động trên các định danh loại bên trong có thể nhìn thấy pg_attributenhưng không có trong information_schema. Thí dụ

SELECT a.attname as column_name, format_type(a.atttypid, a.atttypmod) AS data_type
FROM pg_attribute a JOIN pg_class b ON a.attrelid = b.relfilenode
WHERE a.attnum > 0 -- hide internal columns
AND NOT a.attisdropped -- hide deleted columns
AND b.oid = 'my_table'::regclass::oid; -- example way to find pg_class entry for a table

Dựa trên https://gis.stackexchange.com/a/97834 .


1
Đối với hậu thế, với pg10 thay thế b.relfilenodebằngb.oid
tswaters
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.