Pilih tipe data bidang di postgres

165

Bagaimana saya mendapatkan tipe data bidang tertentu dari tabel di postgres? Sebagai contoh, saya memiliki tabel berikut ini, student_details (stu_id integer, stu_name varchar (30), join_date timestamp);

Dalam hal ini menggunakan nama bidang / atau cara lain, saya perlu mendapatkan tipe data dari bidang tertentu. Apakah ada kemungkinan?

Nathan Villaescusa
sumber
1
Juga ditanyakan & dijawab stackoverflow.com/q/20194806/65458
Piotr Findeisen

Jawaban:

173

Anda bisa mendapatkan tipe data dari information_schema (8,4 dokumen yang dirujuk di sini, tetapi ini bukan fitur baru):

=# 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)
Wayne Conrad
sumber
Sangat sederhana dan menyenangkan! Sekarang saya dapat mengganti permintaan saat ini yang saya temukan yaitu 310 karakter (tanpa nama tabel), 4 tabel bergabung, tidak sadar skema, mahal, dan yang memberikan 'int4' dan lainnya sebagai tipe bukan bilangan bulat. Terima kasih!
beberapa
2
PostgreSQL memungkinkan Anda untuk memiliki nama tabel yang sama (bahkan tabel yang identik) di banyak skema. Cara kuat untuk menulis bahwa klausa WHERE mempertimbangkan kemungkinan itu: where table_catalog = ? and table_schema = ? and table_name = ?;Tetapi tampilan information_schema ini tidak mempertimbangkan bahwa DDL mungkin menggunakan domain .
Mike Sherrill 'Cat Recall'
1
Ini tidak akan memberi Anda jenis array, sehingga harus digunakan bersamapg_typeof
Daria
146

Anda dapat menggunakan fungsi pg_typeof () , yang juga berfungsi dengan baik untuk nilai arbitrer.

SELECT pg_typeof("stu_id"), pg_typeof(100) from student_details limit 1;
Nathan Villaescusa
sumber
ini mengembalikan baris per catatan dalam tabel. Jangan jalankan jika Anda memiliki jutaan catatan
Saarang
3
Ini berfungsi dengan baik jika Anda perlu menentukan jenis perhitungannya. misalnya, SELECT pg_typeof( date_part( 'year', now() ) ) AS exprmungkin berbeda dari yang Anda harapkan.
Leo Orientis
hal yang cerdas di sini adalah bahwa pg_typeofbekerja untuk bidang yang keluar dari prosedur tersimpan, yang tabel backend, jika bahkan ada, tidak diketahui / tidak jelas. select state, qstart, pg_typeof(qstart) as ty_qstart from listconn(). information_schema tidak akan banyak membantu di sini.
JL Peyret
40

Coba permintaan ini:

SELECT column_name, data_type FROM information_schema.columns WHERE 
table_name = 'YOUR_TABLE' AND column_name = 'YOUR_FIELD';
Romulo Freires
sumber
4
table_name = 'YOUR_TABLE' AND column_name = 'YOUR_FIELD';
haitham
38

jalankan psql -Elalu\d student_details


sumber
sederhana dan bermanfaat
horoyoi
11

Jika Anda menyukai solusi 'Mike Sherrill' tetapi tidak ingin menggunakan psql, saya menggunakan kueri ini untuk mendapatkan informasi yang hilang:

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'

dengan hasil:

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

Tampilan skema informasi dan pg_typeof () mengembalikan informasi tipe yang tidak lengkap. Dari jawaban-jawaban ini, psqlberikan informasi jenis yang paling tepat. (OP mungkin tidak membutuhkan informasi yang tepat seperti itu, tetapi harus mengetahui keterbatasannya.)

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

Menggunakan psqldan \d public.testdengan benar menunjukkan penggunaan tipe data test_domain, panjang kolom varchar (n), dan ketepatan dan skala kolom numerik (p, s).

sandbox = # \ d public.test
             Tabel "public.test"
 Kolom | Ketik | Pengubah
--------- + ----------------------- + -----------
 test_id | test_domain |
 test_vc | karakter bervariasi (15) |
 test_n | numerik (15,3) |
 big_n | bigint |
 ip_addr | inet |

Permintaan ini terhadap tampilan information_schema tidak menunjukkan penggunaan test_domainsama sekali. Itu juga tidak melaporkan detail kolom varchar (n) dan numerik (p, s).

select column_name, data_type 
from information_schema.columns 
where table_catalog = 'sandbox'
  and table_schema = 'public'
  and table_name = 'test';
nama_kolom | tipe data
------------- + -------------------
 test_id | karakter bervariasi
 test_vc | karakter bervariasi
 test_n | numerik
 big_n | bigint
 ip_addr | inet

Anda mungkin bisa mendapatkan semua informasi itu dengan bergabung dengan pandangan information_schema lain, atau dengan menanyakan tabel sistem secara langsung. psql -Emungkin membantu dengan itu.

Fungsi pg_typeof()dengan benar menunjukkan penggunaan test_domain, tetapi tidak melaporkan detail kolom varchar (n) dan numerik (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 | test_n | big_n | ip_addr
------------- + ------------------- + --------- + ------ - + ---------
 test_domain | karakter yang bervariasi | numerik | bigint | inet
Mike Sherrill 'Cat Recall'
sumber
4

Menarik tipe data dari information_schemadimungkinkan, tetapi tidak nyaman (perlu menggabungkan beberapa kolom dengan casepernyataan). Atau seseorang dapat menggunakan format_typefungsi bawaan untuk melakukan itu, tetapi ia bekerja pada pengidentifikasi tipe internal yang terlihat pg_attributetetapi tidak di information_schema. Contoh

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

Berdasarkan https://gis.stackexchange.com/a/97834 .

Piotr Findeisen
sumber
1
Untuk anak cucu, dengan pg10 ganti b.relfilenodedenganb.oid
tswaters