Jeg ser etter en presis informasjon i en database som jeg ikke har kunnskap om.
Det er et tredjepartsprodukt, de svarer tregt på noen spørsmål, og jeg vet at dataene ligger inne i db, så jeg vil gjøre litt retro-engineering.
Gitt en tabell, er det mulig å ha en liste over navnene på kolonnene for denne tabellen?
For eksempel i SqlServer er det mulig å dumpe en tabell i en gjenbrukbar CREATE
utsagn, som tekstlig viser alle kolonnene tabellen er sammensatt av.
Kommentarer
Svar
I tillegg til kommandolinjen \d+ <table_name>
du allerede fant, kan du bruk også Informasjonsskjema for å slå opp kolonnedataene ved å bruke information_schema.columns
:
SELECT * FROM information_schema.columns WHERE table_schema = "your_schema" AND table_name = "your_table" ;
Merk: I henhold til eksemplet ovenfor, sørg for at verdiene er omsluttet av anførselstegn.
Kommentarer
- I psql bruker du
\x on
eller\pset expanded on
for å gjøre spørringen resultater lineære (i stedet for tabellformede) og dermed lettere å lese stackoverflow.com/a/9605093/513397 - I gjeldende versjoner (prøvd det i 9.6) kan du gjøre i psql
\d+ public.*
for å få beskrivelsen (skjema + indeces / fkeys / triggers) av alle tabellene og visningene dine ipublic
skjema. Vi bruker det i vårt pre-commit-hook-skript for å holde oversikt over endringer i DB-en som er gjort av hver commit. - VELG kolonnenavn for å få bare kolonnenavn
Svar
Som et supplement til de andre svarene, vil selv en SELECT-setning som ikke gir noen rader, utsette kolonnenavnene for deg og for applikasjonskoden.
select * from table_name where false;
Tillatelser kan komme til å spille med noen av disse tilnærmingene.
Kommentarer
- Jeg antar at du mener å overføre denne SQL til kommandoen psql. Jeg foreslår at du bruker alternativet –no-psqlrc i så fall for å unngå overraskelser i utdataene.
- Med unntak av de skjulte kolonnene, som måtte spesifiseres for å bli valgt (som pg_class.oid)
Svar
informasjonskjema er den langsomme og sikre måten: den er standardisert og i stor grad bærbar til andre databaser som støtter den. Og det vil fortsette å fungere på tvers av store versjoner.
viser i informasjonsskjemaet ofte med mange tabeller fra systemkataloger for å oppfylle et strengt standardisert format – hvorav mange bare er dødfrakt mesteparten av tiden. Dette gjør dem til treg .
Postgres-utviklerne gir ikke løfter, men grunnleggende (som det som trengs her) kommer ikke til å endres på tvers av hovedversjoner.
psql
(det opprinnelige kommandolinjegrensesnittet) tar selvfølgelig hurtigbanen og spør kilden direkte . Hvis du starter psql
med parameteren -E
, er SQL bak tilbakeslagskommandoer som \d
vises. Eller \set ECHO_HIDDEN on
fra psql-kommandolinjen. Fra derfra kan du bygge et svar på spørsmålet ditt.
Gitt en tabell, er det mulig å ha en liste over navnene på kolonnene for dette tabell.
SELECT attrelid::regclass AS tbl , attname AS col , atttypid::regtype AS datatype -- more attributes? FROM pg_attribute WHERE attrelid = "myschema.mytable"::regclass -- table name, optionally schema-qualified AND attnum > 0 AND NOT attisdropped ORDER BY attnum;
Raskere enn som spør information_schema.columns
. Prøv EXPLAIN ANALYZE
for å se selv. Fortsatt betyr det ikke noe for en engangsoppslag. Men kan utgjøre en forskjell hvis det brukes i et spørsmål / en funksjon som gjentas mange ganger.
Det er også subtile forskjeller i synlighet. Detaljert sammenligning:
Kommentarer
- Liker virkelig at du viser deg
-E
og viser folk hvordan du får tak i sql med psql. - Jeg er enig.Jeg kjørte noen hastighetstester og pg_catalog kjører mer enn 2x så raskt
Svar
psql
på PostgreSQL 11+
Hvis du leter etter kolonnetypene i et spørsmål, kan du bruke psql
«s \gdesc
SELECT NULL AS zero, 1 AS one, 2.0 AS two, "three" AS three, $1 AS four, sin($2) as five, "foo"::varchar(4) as six, CURRENT_DATE AS now \gdesc Column | Type --------+---------------------- zero | text one | integer two | numeric three | text four | text five | double precision six | character varying(4) now | date (8 rows)
Svar
Bare PostgreSQL
Dette er noe hokey, men kan være en konkurrent hvis du leter etter kortest mulig SQL:
SELECT json_object_keys(to_json(json_populate_record(NULL::schema_name.table_name, "{}"::JSON)))
eller enda kortere (forutsatt at det er minst en rad i tabellen)
SELECT json_object_keys(to_json((SELECT t FROM schema_name.table_name t LIMIT 1)))
Oppføringen bevarer bestillingen. Hvis du ikke bryr deg om bestillingen og har installert hstore
, kan du gjøre enda kortere
SELECT skeys(hstore(NULL::schema_name.table_name))
\dt[+] table_name
ipsql
.