Re: plpgsql function help

From: "Tyler Hains" <thains(at)profitpointinc(dot)com>
To: tgl <tgl(at)sss(dot)pgh(dot)pa(dot)us>
Cc: pgsql-novice <pgsql-novice(at)postgresql(dot)org>
Subject: Re: plpgsql function help
Date: 2010-03-30 16:27:34
Message-ID: H000006900b580d5.1269966452.mailpa.profitpointinc.com@MHS
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-novice

> > I am trying to get a function to return an integer field pulled from
a
> > different database using dblink. I am getting a run-time error. Here
is
> > the function and the error:

> > CREATE OR REPLACE FUNCTION get_db_id()
> > RETURNS INTEGER AS
> > $BODY$
> > DECLARE
> > client_ids INTEGER[];
> > db_id INTEGER;
> > BEGIN
> > SELECT INTO client_ids DISTINCT client_id FROM clients;
> > SELECT INTO db_id dblink('dbname=system',
> > 'SELECT database_id FROM clients WHERE client_id =
> > '||client_ids[0]);
> > RETURN db_id;
> > END;
> > $BODY$
> > LANGUAGE 'plpgsql' IMMUTABLE
> > COST 100;

> > ERROR: array value must start with "{" or dimension information
> > Context: PL/pgSQL function "get_db_id" line 5 at SQL statement

> Well, you've got a few problems here. You seem to be hoping that
SELECT
> DISTINCT will return an array just because you tell it to assign into
an
> array variable. It will not; INTO does not affect the semantics of
the
> statement, only where the result goes.

> If you are using a version new enough to have array_agg() you could
use
> that to make an array from the client_id values, but I'm rather
unclear
> on the point of this coding anyway. Why are you pulling all of the
> client_id values from the table when you only want to use one? And
> which one do you think you're going to get? (Hint: it'd be pretty
> indeterminate with any coding like this.) There are a number of ways
to
> fix this depending on what you actually need, but it's hard to
recommend
> anything without knowing what the intent is.

> The other problem is that that dblink call won't work, once you get to
> it. dblink needs to have an AS clause telling it what the expected
> result type is. You need something along the lines of

> SELECT INTO db_id * FROM
> dblink('dbname=system', 'SELECT database_id FROM clients WHERE
client_id = '||client_ids[0])
> AS x(database_id int);

> regards, tom lane

Thanks! Here is my working function for the curious:

-- Essentially returns this.database_id while in a client database,
looking
-- it up from the system database.
CREATE OR REPLACE FUNCTION get_db_id()
RETURNS integer AS
$BODY$
DECLARE
rec RECORD;
BEGIN
SELECT client_id INTO rec FROM clients LIMIT 1;
SELECT * INTO rec FROM dblink('dbname=system',
'SELECT database_id FROM clients WHERE client_id =
'||rec.client_id)
AS db(db_id INTEGER);
RETURN rec.db_id;
END;
$BODY$
LANGUAGE 'plpgsql' IMMUTABLE
COST 100;

In response to

Browse pgsql-novice by date

  From Date Subject
Next Message Daniel Staal 2010-03-30 17:36:11 Re: Table inheritance
Previous Message A. Kretschmer 2010-03-30 14:09:10 Re: FW: plpgsql function help