2010-12-02 48 views
1

Après l'excellent answer par Alexandre GUIDET, je tenté d'exécuter la requête suivante: cependant,Utiliser une requête pour définir le type de colonne dans 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, se plaint de syntaxe incorrecte. Plus précisément, il est dit que je ne peux pas écrire: create table egg (id (SELECT.
Y a-t-il des solutions de contournement? Je ne peux pas convertir le résultat d'une requête en texte et le réutiliser en tant que requête?

Répondre

3

Il existe un beaucoup plus simple de faire cela.

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

condition Only est que la table de modèle contient au moins une rangée. Voir le manual on pg_typeof()

Comme Milen a écrit, vous devez EXECUTE instructions DDL dynamiques comme ceci.
beaucoup plus simple DO déclaration:

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

Ou, si vous n'êtes pas sûr de la table de modèle a toutes les lignes:

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

Ces conditions semblent redondantes, puisque vous recherchez une colonne spécifique tout

format() nécessite Postgres 9.1+.

connexes:

1

Vous pouvez convertir cette requête à un function ou (si vous avez Postgres 9.0) à an anonymous code block:

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

Vous pouvez avoir une table une définition ou d'une requête, mais pas les deux. Peut-être que vous pensez à la commande select into.