DBLINK(3)

πŸ“¦ version 14.24, in opensuse-leap 16.0

okay so bestie, this is the dblink(3) page from the PostgreSQL 14.24 docs and I'm gonna walk you through it because it's genuinely so useful and nobody explains it right. sit down, grab a lil snack πŸ“


✨ NAME ✨

dblink β€” executes a query in a remote database. that's it. that's the whole vibe. you're reaching through space to another database and asking it stuff πŸ¦‹


🌸 SYNOPSIS 🌸

dblink(text connname, text sql [, bool fail_on_error]) returns setof record
dblink(text connstr, text sql [, bool fail_on_error]) returns setof record
dblink(text sql [, bool fail_on_error]) returns setof record

three whole flavors, pick your fighter πŸ’…


πŸ’– DESCRIPTION πŸ’–

so dblink executes a query β€” usually a SELECT, but lowkey it can be any SQL statement that returns rows β€” in a remote database. no cap, that's the whole job.

here's the part where you gotta pay attention though πŸ‘€ when you give it two text arguments, the first one is first looked up as a persistent connection's name. if it's found, the command is executed on that connection, easy. if it's not found, then the first argument gets treated as a connection info string exactly as for dblink_connect, and the indicated connection is made just for the duration of this command. so it's like a lil pop-up connection, iconic but temporary ✨


πŸŽ€ ARGUMENTS πŸŽ€

  • connname β€” name of the connection to use. omit this parameter and you get the unnamed connection instead 🫢
  • connstr β€” a connection info string, as previously described for dblink_connect.
  • sql β€” the SQL query you wish to execute in the remote database, for example select * from foo.
  • fail_on_error β€” if true (and that's the default when it's omitted, bestie) then an error thrown on the remote side of the connection causes an error to also be thrown locally. if false, the remote error gets reported locally as a NOTICE instead, and the function returns no rows. so like, the drama is contained πŸ’€

πŸ¦‹ RETURN VALUE πŸ¦‹

the function returns the row(s) produced by the query. and here's the thing β€” since dblink can be used with any query, it's declared to return record, rather than specifying any particular set of columns. which means you must specify the expected set of columns in the calling query β€” otherwise PostgreSQL would not know what to expect. it's giving "you have to tell me what to look for or I'm lost" 😭

here's an example:

SELECT *
    FROM dblink('dbname=mydb options=-csearch_path=',
                'select proname, prosrc from pg_proc')
      AS t1(proname name, prosrc text)
    WHERE proname LIKE 'bytea%';

the "alias" part of the FROM clause must specify the column names and types that the function will return. (specifying column names in an alias is actually standard SQL syntax, but specifying column types is a PostgreSQL extension β€” we're just extra like that πŸ’…) this allows the system to understand what * should expand to, and what proname in the WHERE clause refers to, in advance of trying to execute the function. so smart.

at run time, an error will be thrown if the actual query result from the remote database does not have the same number of columns shown in the FROM clause. the column names need not match, however, and dblink does not insist on exact type matches either. it will succeed so long as the returned data strings are valid input for the column type declared in the FROM clause. flexible queen πŸ”₯


⭐ NOTES ⭐

a convenient way to use dblink with predetermined queries is to create a view. this allows the column type information to be buried in the view, instead of having to spell it out in every single query. no more repeating yourself, we love to see it πŸ™ˆ

for example:

CREATE VIEW myremote_pg_proc AS
  SELECT *
    FROM dblink('dbname=postgres options=-csearch_path=',
                'select proname, prosrc from pg_proc')
    AS t1(proname name, prosrc text);

SELECT * FROM myremote_pg_proc WHERE proname LIKE 'bytea%';

πŸ”₯ EXAMPLES πŸ”₯

here's the whole glow-up tour, in order. first up, dblink with an inline connection string:

SELECT * FROM dblink('dbname=postgres options=-csearch_path=',
                     'select proname, prosrc from pg_proc')
  AS t1(proname name, prosrc text) WHERE proname LIKE 'bytea%';
  proname   |   prosrc
------------+------------
 byteacat   | byteacat
 byteaeq    | byteaeq
 bytealt    | bytealt
 byteale    | byteale
 byteagt    | byteagt
 byteage    | byteage
 byteane    | byteane
 byteacmp   | byteacmp
 bytealike  | bytealike
 byteanlike | byteanlike
 byteain    | byteain
 byteaout   | byteaout
(12 rows)

then connect to that unnamed connection so you can reuse it:

SELECT dblink_connect('dbname=postgres options=-csearch_path=');
 dblink_connect
----------------
 OK
(1 row)

and now you can skip the connection string entirely, because she's already connected 😌

SELECT * FROM dblink('select proname, prosrc from pg_proc')
  AS t1(proname name, prosrc text) WHERE proname LIKE 'bytea%';
  proname   |   prosrc
------------+------------
 byteacat   | byteacat
 byteaeq    | byteaeq
 bytealt    | bytealt
 byteale    | byteale
 byteagt    | byteagt
 byteage    | byteage
 byteane    | byteane
 byteacmp   | byteacmp
 bytealike  | bytealike
 byteanlike | byteanlike
 byteain    | byteain
 byteaout   | byteaout
(12 rows)

now let's do a named connection, which is the main character energy move πŸ‘‘

SELECT dblink_connect('myconn', 'dbname=regression options=-csearch_path=');
 dblink_connect
----------------
 OK
(1 row)

and then call it by name:

SELECT * FROM dblink('myconn', 'select proname, prosrc from pg_proc')
  AS t1(proname name, prosrc text) WHERE proname LIKE 'bytea%';
  proname   |   prosrc
------------+------------
 bytearecv  | bytearecv
 byteasend  | byteasend
 byteale    | byteale
 byteagt    | byteagt
 byteage    | byteage
 byteane    | byteane
 byteacmp   | byteacmp
 bytealike  | bytealike
 byteanlike | byteanlike
 byteacat   | byteacat
 byteaeq    | byteaeq
 bytealt    | bytealt
 byteain    | byteain
 byteaout   | byteaout
(14 rows)
πŸ’€ heads up: notice that last result set has 14 rows and a different ordering than the earlier ones β€” that's just what the remote database handed back, so don't go assuming the rows come out in any particular order, bestie.

okay that's the whole page, go forth and query remotely πŸ’œ this has been dblink, page 3 of the manual, straight out of the PostgreSQL 14.24 documentation and dated 2026 β€” periodt. πŸŽ€βœ¨

πŸ“¦ where this page comes from