Обсуждение: How to use dblink within pl/pgsql function:

Поиск
Список
Период
Сортировка

How to use dblink within pl/pgsql function:

От
Clive Page
Дата:
What I'd like to do is use dblink to extract a few rows from a remote
database and manipulate these within a function in pl/pgsql.  Something
like this:

CREATE OR REPLACE FUNCTION find() RETURNS INTEGER AS '
  DECLARE
    count INTEGER:
    myrec RECORD;
  BEGIN
  FOR myrec IN SELECT * FROM DBLINK(''select x,y from mytab'') as
     temp(x integer, y real) LOOP
     count := count + 1;
  END LOOP;
  RETURN count;
END; ' LANGUAGE 'plpgsql';


But this syntax does not work, and I cannot find a form which does work.
Does anyone know how to do this?

Thanks in advance.

--
Clive Page


Re: How to use dblink within pl/pgsql function:

От
Joe Conway
Дата:
Clive Page wrote:
> What I'd like to do is use dblink to extract a few rows from a remote
> database and manipulate these within a function in pl/pgsql.  Something
> like this:
>
> CREATE OR REPLACE FUNCTION find() RETURNS INTEGER AS '
>   DECLARE
>     count INTEGER:
>     myrec RECORD;
>   BEGIN
>   FOR myrec IN SELECT * FROM DBLINK(''select x,y from mytab'') as
>      temp(x integer, y real) LOOP
>      count := count + 1;
>   END LOOP;
>   RETURN count;
> END; ' LANGUAGE 'plpgsql';
>
>
> But this syntax does not work, and I cannot find a form which does work.
> Does anyone know how to do this?

You didn't show us the specific error you get, making it difficult to help.

Offhand I see two errors in your script above unrelated to the use of
dblink, and possibly one related to dblink. First, the line "count
INTEGER:" ends in a colon instead of the required semicolon. Second, if
you don't initialize "count" to something other than NULL, adding 1 to
it will still add null. Try this:

CREATE OR REPLACE FUNCTION find() RETURNS INTEGER AS '
   DECLARE
     count INTEGER := 0;
     myrec RECORD;
   BEGIN
   FOR myrec IN SELECT * FROM DBLINK(''select x,y from mytab'') as
      temp(x integer, y real) LOOP
      count := count + 1;
   END LOOP;
   RETURN count;
END; ' LANGUAGE 'plpgsql';

The dblink issue is that you've used a form of dblink that requires you
to have previously set up a connection. If you call your find() function
without first establishing that connection, you'll get a "ERROR:
connection not available" or something similar. See the dblink docs.

Joe


Re: How to use dblink within pl/pgsql function:

От
Clive Page
Дата:
Thanks to Joe Conway for pointing out a couple of typos in what I posted
(the original code that I used didn't have quite as many, I edited it to
try to simplify).  He also pointed out that I had not initialised my
'count' variable, which was a genuine mistake.  I am pleased to say that
the corrected function does work as expected:

CREATE OR REPLACE FUNCTION find() RETURNS INTEGER AS '
  DECLARE
    count INTEGER := 0;
    myrec RECORD;
  BEGIN
  FOR myrec IN SELECT * FROM DBLINK(''hostaddr=127.0.0.1'',
   ''select ra, decl from twomass where errbox &&
   box(point(120.45,0.5),point(120.50,0.75))'') as
     temp(x float8, y float8) LOOP
     count := count + 1;
  END LOOP;
  RETURN count;
END; ' LANGUAGE 'plpgsql';

I can use it in a query such as:

SELECT * FROM find();

And it returns the number of rows returned from the join using R-trees.
Of course there are easier ways of doing what this function does, I just
wanted to get that working as a basis on which to build something more
advanced.

--
Clive Page