2

I have two separate databases (MySQL and PostgreSQL) that maintain different data-sets from different departments in my organization-- this can't be changed. I need to connect to one to get a list of symbols or ids from the first DB with a DBAPI in python and request the other set and operate on it.

(I've spent a lot of time on this approach, and it makes sense because of other components in my architecture, so unless there is a much better alternative, I'd like to stick with this method.)

CREATE TABLE foo (fooid int, foosubid int, fooname text);
INSERT INTO foo VALUES (1, 1, 'Joe');
INSERT INTO foo VALUES (1, 2, 'Ed');
INSERT INTO foo VALUES (2, 1, 'Mary');

CREATE FUNCTION get_results(text[]) RETURNS SETOF record AS $$
SELECT fooname, fooid, foosubid FROM foo WHERE name IN $1;
$$ LANGUAGE SQL;

In reality my SQL is much more complicated, but I think this method completely describes the purpose. Can I pass in an arbitrary length parameter into a stored procedure or user defined function and return a result set?

I would like to call the function like:

SELECT * FROM get_results(('Joe', 'Ed'));
SELECT * FROM get_results(('Joe', 'Mary'));
SELECT * FROM get_results(('Ed'));

I believe using the IN and passing these parameters (if it's possible) would give me the same (or comparable) performance as a JOIN. For my current use case the symbols won't exceed 750-1000 'names', but if performance is an issue here I'd like to know why, as well.

3 Answers 3

3

Row vs Array constructor

('Joe', 'Ed') is equivalent to ROW('Joe', 'Ed') and creates a new row.

But your function accepts an array. To create one, call it with an Array constructor:

SELECT * FROM get_results(ARRAY['Joe', 'Ed']);

Variadic functions

You can declare your input parameter as VARIADIC like so

CREATE FUNCTION get_results(VARIADIC text[]) RETURNS SETOF record AS $$
SELECT fooname, fooid, foosubid FROM foo WHERE name = ANY($1);
$$ LANGUAGE SQL;

It accepts a variable number of arguments. You can call it like this:

SELECT * FROM get_results('Joe', 'Ed');

More on functions with variable length arguments: http://www.postgresql.org/docs/9.4/static/xfunc-sql.html

Sign up to request clarification or add additional context in comments.

Comments

1

Use RETURNS TABLE instead of RETURNS SETOF record. This will simplify the function calls.

You cannot use IN operator in that way. Use ANY instead.

CREATE FUNCTION get_results(text[]) 
RETURNS TABLE (fooname text, fooid int, foosubid int) 
AS $$
    SELECT fooname, fooid, foosubid 
    FROM foo 
    WHERE fooname = ANY($1);
$$ LANGUAGE SQL;

SELECT * FROM get_results(ARRAY['Joe']);

 fooname | fooid | foosubid 
---------+-------+----------
 Joe     |     1 |        1
(1 row)

If the function returns setof records you have to put a column definition list in every function call:

SELECT * 
FROM get_results(ARRAY['Joe']) AS (fooname text, fooid int, foosubid int)

Comments

1

Jared, If you want just to pass an array into a procedure or function call in where clause, you can try using this:

CREATE FUNCTION get_results(text[]) RETURNS SETOF record AS $$
SELECT fooname, fooid, foosubid FROM foo WHERE name = any($1);
$$ LANGUAGE SQL;

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.