Thread: Replacing a table

Replacing a table

From
Francisco Reyes
Date:
I have some report tables which get re-created every day.
Previously I had something like
drop table
select .... into table

I thought that given that the queries for these report tables take 20 to
30 minutes I would try something like
begin
drop
select ... into table
commit

However once I ran a test case I was unable to connect to the table.

What would be the way to replace tables?
The output is fairly small so I was thinking about something like:
Create data to cursor
drop table
select from cursor into table

Is this the best way?



Re: Replacing a table

From
Neil Conway
Date:
Francisco Reyes <lists@natserv.com> writes:
> I have some report tables which get re-created every day.
> Previously I had something like
> drop table
> select .... into table

> What would be the way to replace tables?

Try creating the summary data in new table with a temporary name, then
starting a transaction, dropping the original table, renaming the new
table to the proper name, and then committing the transaction.

Cheers,

Neil

--
Neil Conway <neilc@samurai.com> || PGP Key ID: DB3C29FC

Re: Replacing a table

From
Tom Lane
Date:
Francisco Reyes <lists@natserv.com> writes:
> I thought that given that the queries for these report tables take 20 to
> 30 minutes I would try something like
> begin
> drop
> select ... into table
> commit

> However once I ran a test case I was unable to connect to the table.

Yeah, because the DROP will acquire exclusive lock on the table;
this approach is rollback-safe but not transaction-friendly.
Consider

begin
select into new_table
drop table
alter table new_table rename to table
commit

which does not hold the exclusive lock as long.

> What would be the way to replace tables?
> The output is fairly small so I was thinking about something like:
> Create data to cursor
> drop table
> select from cursor into table

If you don't mind copying the data then this is probably the best
bet:

begin
select ... into temp table ttable
lock table table
delete from table
insert into table select * from ttable
drop table ttable
commit

(A vacuum or truncate would be nice here to actually remove the deleted
rows, but you can't put either inside a transaction block at present.
A "vacuum table" outside the transaction block will have to do instead.)

The reason this is better is that it doesn't DROP the table, which means
you do not lose indexes, foreign keys, views, etc that reference the
table.  Also it eliminates a race condition: someone trying to access
the old table just after you drop it would get an error, even though
there is a new table of the same name by the time he gets to proceed.

            regards, tom lane