patternsqlMinor
PostgreSQL stored procedure to return rows or empty set
Viewed 0 times
postgresqlrowsstoredreturnemptyprocedureset
Problem
I have a stored procedure, which
And I want to do this: If this 'dynamic query' returns >= 10 rows, I want to return them, but if it returns only < 10 rows, I don't want to return anything (empty set of
I tried:
If I do
I have it like this:
and it works, but I didn't want to do this query two times.
RETURNS SETOF ct_custom_type and inside I doRETURN QUERY EXECUTE 'some dynamic query'And I want to do this: If this 'dynamic query' returns >= 10 rows, I want to return them, but if it returns only < 10 rows, I don't want to return anything (empty set of
ct_custom_type).I tried:
RETURN QUERY EXECUTE 'some dynamic query'
GET DIAGNOSTICS variable = ROW_COUNT;
IF variable < 10 THEN
# I don't know what to do here or how to accomplish this
END IF;If I do
RETURN QUERY SELECT 0, 0, ''::text; in the IF block (because ct_custom_type is a composite type of (integer, integer, text), it just adds this 'empty row' to previous query result, but I don't want to return anything in this case, I can do RETURN;, but it will return that previous result and I want to discard it.I have it like this:
EXECUTE 'dynamic query';
GET DIAGNOSTICS variable = ROW_COUNT;
IF variable >= 10 THEN
RETURN QUERY EXECUTE 'dynamic query';
END IF;and it works, but I didn't want to do this query two times.
Solution
You can do something along the following lines:
This way you have to perform your original query only once. All other statements work on the temporary table.
test=> CREATE OR REPLACE FUNCTION temptabl(cnt integer)
RETURNS SETOF integer AS
$body$
BEGIN
CREATE TEMPORARY TABLE tmp_container ON COMMIT DROP AS
SELECT a
FROM generate_series(1, cnt) t(a);
IF (SELECT count(1) FROM tmp_container) > 5
THEN
RETURN QUERY SELECT a FROM tmp_container;
END IF;
END;
$body$
LANGUAGE plpgsql;
test=> SELECT * FROM temptabl(4);
temptabl
----------
(0 rows)
test=> SELECT * FROM temptabl(6);
temptabl
----------
1
2
3
4
5
6
(6 rows)This way you have to perform your original query only once. All other statements work on the temporary table.
Code Snippets
test=> CREATE OR REPLACE FUNCTION temptabl(cnt integer)
RETURNS SETOF integer AS
$body$
BEGIN
CREATE TEMPORARY TABLE tmp_container ON COMMIT DROP AS
SELECT a
FROM generate_series(1, cnt) t(a);
IF (SELECT count(1) FROM tmp_container) > 5
THEN
RETURN QUERY SELECT a FROM tmp_container;
END IF;
END;
$body$
LANGUAGE plpgsql;
test=> SELECT * FROM temptabl(4);
temptabl
----------
(0 rows)
test=> SELECT * FROM temptabl(6);
temptabl
----------
1
2
3
4
5
6
(6 rows)Context
StackExchange Database Administrators Q#40214, answer score: 8
Revisions (0)
No revisions yet.