Reputation: 1844
I have a VIEW
for which I use a certain SELECT
statement, where there is a CASE
condition, which, based on some condition being TRUE or FALSE decides, whether to increment the counter or use the current value.
As far as I know, any view of a SELECT
statement is generated every time it is referenced, so I would like to recreate the SEQUENCE
every time that happens.
Example:
CREATE TABLE num(
n BIGINT PRIMARY KEY
);
INSERT INTO num(n) VALUES (1), (2), (3), (4), (5), (6), (7), (8), (9);
CREATE TEMP SEQUENCE seq START 1;
SELECT nextval('seq');
SELECT
CASE WHEN n % 2 = 0 THEN nextval('seq')
ELSE currval('seq')
END AS test,
n
FROM num;
I had to insert SELECT nextval('seq')
before the SELECT
statement, otherwise it yielded
ERROR: currval of sequence "seq" is not yet defined in this session
And at the end of the day this code doesn't recreate the SEQUENCE
each time, as it would only use the created one to generate new values.
This chunk of code works as expected, but smells like bad database design from my side.
Would any one of you guys know, how to create a new SEQUENCE
object every time the SELECT
is called? Or is there another way? I feel like there should be a clean and clear way of doing that, and I'm surely missing out on something!
Upvotes: 0
Views: 1914
Reputation: 1270793
For your example, you can set the value of the sequence in the SELECT
:
SELECT (CASE WHEN n % 2 = 0 THEN nextval('seq')
ELSE currval('seq')
END) AS test,
n
FROM num CROSS JOIN
(SELECT setval('seq', 1)) s;
The FROM
clause should be evaluated before the outer SELECT
, so the outer SELECT
should start at the specified value.
Here is a db<>fiddle.
I should note that this does suggest a problem with the database design. However, I could imagine a view containing:
FROM (SELECT NEXT_VALUE('view_cnt')) x CROSS JOIN
. . .
To count the number of times the view has been called. That might be handy information.
Upvotes: 2