2015-11-20 4 views
1

У меня есть следующие функции в моей базе данных PostgreSQL:Postgres: Временная таблица в функции постоянна. Зачем?

CREATE OR REPLACE FUNCTION get_unused_part_ids() 
    RETURNS integer[] AS 
$BODY$ 
DECLARE 
    part_ids integer ARRAY; 
BEGIN 
    create temporary table tmp_parts 
     as 
    select vendor_id, part_number, max(price) as max_price 
    from refinery_akouo_parts 
    where retired = false 
    group by vendor_id, part_number 
    having min(price) < max(price); 

    -- do some work etc etc 

    -- simulate ids being returned 
    part_ids = '{1,2,3,4}'; 
    return part_ids; 

END; 
$BODY$ 
    LANGUAGE plpgsql VOLATILE 
    COST 100; 
ALTER FUNCTION get_unused_part_ids() 
    OWNER TO postgres; 

компилируется, но когда я бег:

select get_unused_part_ids(); 

временной таблицы, tmp_parts, по-прежнему существует. После этого я могу сделать выбор. Простите меня, поскольку я привык к определенной функциональности с помощью t-sql/MSSQL. Это не относится к MSSQL. Что я делаю не так?

ответ

2

Таблица будет удалена только в конце сеанса. Вам нужно указать параметр ON COMMIT, который нужно удалить, и он упадет в конце транзакции.

create temporary table tmp_parts 
    on commit drop 
     as 
    select vendor_id, part_number, max(price) as max_price 
    from refinery_akouo_parts 
    where retired = false 
    group by vendor_id, part_number 
    having min(price) < max(price); 
2

После manual

Временные таблицы автоматически удаляются по окончании сеанса, или, возможно, в конце текущей транзакции (см ON COMMIT ниже)

Сессия заканчивается после отсоединения. Не после совершения транзакции. Поэтому поведение по умолчанию заключается в том, чтобы сохранить временную таблицу до тех пор, пока ваше соединение не будет открыто. Вы должны добавить ON COMMIT DROP; для того чтобы достигнуть желаемого поведения:

create temporary table tmp_parts on commit drop 
     as 
    select vendor_id, part_number, max(price) as max_price 
    from refinery_akouo_parts 
    where retired = false 
    group by vendor_id, part_number 
    having min(price) < max(price) 
on commit drop; 
+1

'on commit drop' в конце инструкции вызывает синтаксическую ошибку. Если вы посмотрите на ответ @ JonathanG, его работы. Измените свой пост за +1. – DJTripleThreat

+0

Хорошая точка, ответ отредактирован. –

+0

спасибо! +1, друг :) – DJTripleThreat

1

Временные таблицы рассматриваются по-разному в двух базах данных. В SQL Server они будут удалены в конце хранимой процедуры, где они создаются автоматически.

В Postgres, временные таблицы назначаются сессии (или сделки), как описано в documentation:

Если указано, то таблица создается в качестве временной таблицы. Временные таблицы автоматически отбрасываются в конце сеанса или необязательно в конце текущей транзакции (см. ВКЛ. КОМИТЕТ ниже). Существующие постоянные таблицы с таким же именем не отображаются для текущего сеанса, пока существует временная таблица, если только они не имеют значения с именами, сопоставляемыми с схемой. Любые индексы, созданные на временной таблице , также являются временными.

Концепция представляет собой разновидность между обычной временной таблицей и глобальной временной таблицей в SQL Server (глобальные временные таблицы начинаются с ##).