Использование запроса для установки типа столбца в PostgreSQL - PullRequest
1 голос
/ 02 декабря 2010

После превосходного ответа Александра GUIDET я попытался выполнить следующий запрос:

 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 жалуется на неправильный синтаксис. В частности, это говорит о том, что я не могу написать: create table egg (id (SELECT.
Есть ли обходные пути? Не могу ли я преобразовать результат запроса в текст и повторно использовать его как запрос?

Ответы [ 3 ]

3 голосов
/ 26 октября 2011

Существует гораздо более простой способ сделать это.

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

Единственным предварительным условием является то, что таблица шаблонов содержит хотя бы одну строку . См. Руководство для pg_typeof ()

Как писал Милен, вам нужно EXECUTE динамические операторы DDL, подобные этим.
Гораздо проще DO утверждение:

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

Или, если вы не уверены, что в таблице шаблонов есть какие-либо строки:

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

Эти условия кажутся избыточными, так как вы ищете какой-либо конкретный столбец любой

format() требуется Postgres 9,1 +.

Связанный:

1 голос
/ 02 декабря 2010

Вы можете преобразовать этот запрос в функцию или (если у вас Postgres 9.0) в блок анонимного кода :

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 голосов
/ 03 декабря 2010

Вы можете иметь таблицу, определение или запрос, но не оба одновременно.Может быть, вы думаете о команде select into.

...