2014-09-26 5 views
3

В соответствии с документацией для each(), она возвращает setof(key text, value text). Однако при использовании его с SELECT я не могу получить доступ к key или value. Я попытался найти информацию о типах record, но все, что я могу найти, это бесполезный бит, связанный с plpgsql.Доступ к элементам записи

Скажем, у меня есть следующая таблица:

CREATE TABLE mytable (
    id SERIAL NOT NULL PRIMARY KEY, 
    data HSTORE NOT NULL 
); 

И я бегу запрос:

SELECT pair 
FROM (
    SELECT each(data) AS pair 
    FROM mytable 
) AS pairs 

я получаю строки типа record:

(key1,value1) 
(key2,value2) 
... 

Если я пытаюсь доступа key или value, я получаю различные ошибки.

  1. Это:

    SELECT pair.key, pair.value 
    FROM (
        SELECT each(data) AS pair 
        FROM mytable 
    ) AS pairs 
    

    Дает:

    ERROR: missing FROM-clause entry for table "pair" 
    LINE 1: pair.key, 
         ^
    ********** Error ********** 
    
    ERROR: missing FROM-clause entry for table "pair" 
    SQL state: 42P01 
    Character: 8 
    
  2. Это:

    SELECT pair.key, pair.value 
    FROM (
        SELECT each(data) AS pair (key, value) 
        FROM mytable 
    ) AS pairs 
    

    Дает:

    ERROR: syntax error at or near "(" 
    LINE 4: each(attributes) AS pair (key, value) 
               ^
    
    ********** Error ********** 
    
    ERROR: syntax error at or near "(" 
    SQL state: 42601 
    Character: 71 
    
  3. Это:

    SELECT pairs.pair.key, pairs.pair.value 
    FROM (
        SELECT each(data) AS pair 
        FROM mytable 
    ) AS pairs 
    

    Дает:

    ERROR: schema "pairs" does not exist 
    
    ********** Error ********** 
    
    ERROR: schema "pairs" does not exist 
    SQL state: 3F000 
    
  4. Это:

    SELECT pair[1], pair[2] 
    FROM (
        SELECT each(data) AS pair 
        FROM mytable 
    ) AS pairs 
    

    Дает:

    ERROR: cannot subscript type record because it is not an array 
    
    ********** Error ********** 
    
    ERROR: cannot subscript type record because it is not an array 
    SQL state: 42804 
    

Как правильно получить доступ к членам типа record в PostgreSQL?

+0

'каждый' предназначен для' hstore', а не 'record'. –

+1

@CraigRinger 'each (hstore)' возвращает 'setof record'. – cpburnz

ответ

3

В PostgreSQL 9.3 используйте LATERAL.

regress=> SELECT p.key, p.value FROM mytable, LATERAL each(data) p; 
key | value 
-----+------- 
a | b 
c | d 
(2 rows) 

В более старых версиях вы должны использовать расширение подстановочных знаков, что немного уродливо.

regress=> SELECT (pair).*         
FROM (
    SELECT each(data) AS pair 
    FROM mytable 
) AS pairs 
; 
key | value 
-----+------- 
a | b 
c | d 
(2 rows) 

Примечание стороны:

each возвращает типизированный набор результатов с OUT параметрами, поэтому имена типа возврата и столбцов известны. Он возвращает набор, т.е.он может возвращать несколько строк для одного вызова:

regress=> \df each 
            List of functions 
Schema | Name | Result data type |   Argument data types   | Type 
--------+------+------------------+-----------------------------------------+-------- 
public | each | SETOF record  | hs hstore, OUT key text, OUT value text | normal 
(1 row) 

Я говорю об этом потому, что функция, которая возвращает record или setof recordбез напечатала OUT параметров не может быть использован так, как я показал выше, вы должны предоставить специальный параметр для таких функций.

Смежные вопросы