2010-12-02 4 views
1

Nach den hervorragenden answer von Alexandre GUIDET zu setzen, versuchte ich die folgende Abfrage ausführen:Abfrage mit dem Spaltentyp in PostgreSQL

create table egg (id (SELECT 
    pg_catalog.format_type(a.atttypid, a.atttypmod) as Datatype 
    FROM 
    pg_catalog.pg_attribute a 
    WHERE 
    a.attnum > 0 
    AND NOT a.attisdropped 
    AND a.attrelid = ( 
    SELECT c.oid 
    FROM pg_catalog.pg_class c 
    LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace 
    WHERE c.relname ~ '^(TABLENAME)$' 
    AND pg_catalog.pg_table_is_visible(c.oid) 
) 
    and a.attname = 'COLUMNNAME')); 

PostgreSQL, aber falsche Syntax beklagt. Konkret heißt es, dass ich nicht schreiben kann: create table egg (id (SELECT.
Gibt es Workarounds? Kann ich das Ergebnis einer Abfrage nicht in Text konvertieren und als Abfrage wiederverwenden?

Antwort

3

Es gibt eine viel einfachere Weise, das zu tun.

SELECT pg_typeof(col)::text FROM tbl LIMIT 1 

einzige Voraussetzung ist, dass die Schablonentabelle mindestens eine Reihe hält. Siehe die manual on pg_typeof()

Wie Milen schrieb, müssen Sie EXECUTE dynamische DDL-Anweisungen wie folgt.
Eine einfachere DO Aussage:

DO $$BEGIN 
EXECUTE 'CREATE TABLE egg (id ' 
     || (SELECT pg_typeof(col)::text FROM tbl LIMIT 1) || ')'; 
END$$; 

Oder, wenn Sie nicht sicher sind, die Vorlage Tabelle alle Zeilen hat:

DO $$BEGIN 
EXECUTE (
    SELECT format('CREATE TABLE egg (id %s)' 
       , format_type(atttypid, atttypmod)) 
    FROM pg_catalog.pg_attribute 
    WHERE attrelid = 'tbl'::regclass -- name of template table 
    AND attname = 'col'    -- name of template column 
    AND attnum > 0 AND NOT attisdropped 
    ); 
END$$; 

Diese Bedingungen scheinen überflüssig, da Sie für eine bestimmte Spalte Suchen

format() erfordert Postgres 9.1+.

Verwandte:

1

Sie können entweder konvertieren, die Abfrage an einen function oder an anonymous code block (wenn Sie Postgres 9.0 haben):

DO $$DECLARE the_type text; 
BEGIN 
    SELECT ... AS datatype INTO the_type FROM <the rest of your query>; 
    EXECUTE 'create table egg (id ' || the_type || <the rest of your create table statement>; 
END$$; 
0

Sie können entweder eine Tabelle, die eine Definition oder eine Abfrage, jedoch nicht beides. Vielleicht denken Sie an den Befehl select into.