Thread: Queue in SQL

Queue in SQL

From
"Gyorgy Molnar"
Date:
Hi!

Question:
I need to store some incoming data and retrieve them one by one (LIFO).
Different processes will manage the storage and the retrieval.
How can I retrieve only the first row from a table?
==================

Explanation
I intend to use libpq and C. as far as I know to retrieve the result from a
query I need to do the following:

BEGIN A TRANSACTION
DECLARE CURSOR cursor FOR SELECT
FETCH one row from cursor
Process
CLOSE cursor
DELETE row
COMMIT

Let say I have 100,000 records in my table, I have to pick up only the first
row. I do not have any special criteria to execute a query, and I only need
the oldest added row (let say the first row if the table is indexed).
How can I narrow the search criteria, not to receive all of the 100,000
record in the result?
Unfortunately, I do not know the internal working of the SELECT. I think it
should create a temporary object to store the result. This object size may
depend on the number of the rows in the result and the size of the stored
data per row. I can fetch the rows one by one using this temporary object.

Kind Regards,
Gyorgy Molnar



Re: Queue in SQL

From
Markus Bertheau
Date:
On Tue, 2001-11-27 at 15:11, Gyorgy Molnar wrote:
> How can I retrieve only the first row from a table?
> ==================
>
> Explanation
> I intend to use libpq and C. as far as I know to retrieve the result from a
> query I need to do the following:
>
> BEGIN A TRANSACTION
> DECLARE CURSOR cursor FOR SELECT
> FETCH one row from cursor
> Process
> CLOSE cursor
> DELETE row
> COMMIT
>
> Let say I have 100,000 records in my table, I have to pick up only the first
> row. I do not have any special criteria to execute a query, and I only need
> the oldest added row (let say the first row if the table is indexed).
> How can I narrow the search criteria, not to receive all of the 100,000
> record in the result?

If I understood you right, you can simply do

select <...> limit 1

Markus Bertheau


Re: Queue in SQL

From
"Andrew G. Hammond"
Date:
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On 2001 November 27 09:11 am, Gyorgy Molnar wrote:

> I need to store some incoming data and retrieve them one by one (LIFO).
> Different processes will manage the storage and the retrieval.
> How can I retrieve only the first row from a table?

DROP TABLE queue; DROP SEQUENCE queue_id_seq;
CREATE TABLE queue (id SERIAL UNIQUE, data TEXT);

- -- to insert into queue
INSERT INTO queue (data) VALUES ('first');
INSERT INTO queue (data) VALUES ('second');

- -- to remove from queue
BEGIN;
LOCK queue IN EXCLUSIVE MODE;
SELECT * FROM queue ORDER BY id LIMIT 1;
DELETE FROM queue WHERE id = 1;     -- use the id retrieved above
COMMIT;

Key features:
- - the SERIAL data type draws it's values from a SEQUENCE, which allows us to 
easily maintain the order of the queue.
- - by marking it UNIQUE, we have implicitly defined an index on the column, 
which will make the ORDER BY clause in the SELECT and the WHERE clause in the 
DELETE more efficient.
- - wrapping the whole thing in a transaction and using a LOCK should ensure 
correct behaviour in a concurrent situation.

- -- 
Andrew G. Hammond     mailto:drew@xyzzy.dhs.org   http://xyzzy.dhs.org/~drew/
56 2A 54 EF 19 C0 3B 43 72 69 5B E3 69 5B A1 1F                  613-389-5481
5CD3 62B0 254B DEB1 86E0  8959 093E F70A B457 84B1
"To blow recursion you must first blow recur" -- me
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.0.6 (GNU/Linux)
Comment: For info see http://www.gnupg.org

iEYEARECAAYFAjwFVTsACgkQCT73CrRXhLHEJQCeNVW/3xh/PTfuRsykUz8+ff55
vVEAniFOBIC4FBEeKFwYKN103YbKXFyd
=WMz8
-----END PGP SIGNATURE-----


Re: Queue in SQL

From
"Christopher Kings-Lynne"
Date:
Hi Gyorgy,

Try this:

BEGIN;
SELECT * FROM table ORDER BY oid LIMIT 1 FOR UPDATE;
DELETE FROM table WHERE oid=(SELECT MIN(oid) FROM table);
COMMIT;

Few notes:

1. You might want to add an index over the oid column:
CREATE INDEX "my_idx" ON table(oid);

2. If you are executing this series from a programming language, you can
probably just change the first SELECT to "SELECT oid, * FROM ..." and just
grab out the oid and pass it is a parameter to the DELETE, rather than
having to do the aggregate subselect.

Chris

> -----Original Message-----
> From: pgsql-sql-owner@postgresql.org
> [mailto:pgsql-sql-owner@postgresql.org]On Behalf Of Gyorgy Molnar
> Sent: Tuesday, 27 November 2001 10:11 PM
> To: pgsql-sql@postgresql.org
> Subject: [SQL] Queue in SQL
>
>
> Hi!
>
> Question:
> I need to store some incoming data and retrieve them one by one (LIFO).
> Different processes will manage the storage and the retrieval.
> How can I retrieve only the first row from a table?
> ==================
>
> Explanation
> I intend to use libpq and C. as far as I know to retrieve the
> result from a
> query I need to do the following:
>
> BEGIN A TRANSACTION
> DECLARE CURSOR cursor FOR SELECT
> FETCH one row from cursor
> Process
> CLOSE cursor
> DELETE row
> COMMIT
>
> Let say I have 100,000 records in my table, I have to pick up
> only the first
> row. I do not have any special criteria to execute a query, and I
> only need
> the oldest added row (let say the first row if the table is indexed).
> How can I narrow the search criteria, not to receive all of the 100,000
> record in the result?
> Unfortunately, I do not know the internal working of the SELECT.
> I think it
> should create a temporary object to store the result. This object size may
> depend on the number of the rows in the result and the size of the stored
> data per row. I can fetch the rows one by one using this temporary object.
>
> Kind Regards,
> Gyorgy Molnar
>
>
> ---------------------------(end of broadcast)---------------------------
> TIP 5: Have you checked our extensive FAQ?
>
> http://www.postgresql.org/users-lounge/docs/faq.html
>