根据下面的错误消息,我猜测答案是“否”(并且 这个谷歌结果),但是有没有办法使用 PostgreSQL 执行跨数据库查询?

databaseA=# select * from databaseB.public.someTableName;
ERROR:  cross-database references are not implemented:
 "databaseB.public.someTableName"

我正在处理跨两个数据库分区的一些数据,尽管数据实际上在两个数据库之间共享(一个数据库中的 userid 列来自 users 其他数据库中的表)。我不知道为什么这是两个独立的数据库而不是模式,但这就是生活......

有帮助吗?

解决方案

笔记:正如最初的提问者所暗示的那样,如果您在同一台计算机上设置两个数据库,您可能想要创建两个 图式 相反 - 在这种情况下,您不需要任何特殊的东西来查询它们。

截至 9.3 更新

您现在可以使用新的 postgres_fdw (外部数据包装器)连接到任何 Postgres 数据库中的表 - 本地或远程。

请注意,有 其他流行数据源的外部数据包装器. 。此时,仅 postgres_fdwfile_fdw 是官方 Postgres 发行版的一部分。

9.3 之前的原始答案

此功能不是默认 PostgreSQL 安装的一部分,但您可以添加它。它被称为 dblink.

我从未使用过它,但它与 PostgreSQL 的其余部分一起维护和分发。如果您使用的是 Linux 发行版附带的 PostgreSQL 版本,则可能需要安装一个名为 postgresql-contrib 的软件包。

其他提示

在得出与您相同的关于跨数据库查询的结论之前,我已经遇到过这个问题。我最终做的是使用模式来划分表空间,这样我就可以将表分组,但仍然查询它们。

数据库链接() -- 在远程数据库中执行查询

dblink在远程数据库中执行查询(通常是选择,但可以是任何返回行的SQL语句)。

当给出两个文本参数时,第一个参数首先被视为持续连接的名称。如果找到,则在该连接上执行命令。如果找不到的话,第一个参数被视为连接信息字符串,则与dblink_connect一样,仅在此命令的持续时间内完成指示的连接。

很好的例子之一:

SELECT * 
FROM   table1 tb1 
LEFT   JOIN (
   SELECT *
   FROM   dblink('dbname=db2','SELECT id, code FROM table2')
   AS     tb2(id int, code text);
) AS tb2 ON tb2.column = tb1.column;

笔记:我提供此信息以供将来参考。 参考资料

只是添加更多信息。

除了当前数据库之外,无法查询其他数据库。由于 PostgreSQL 加载特定于数据库的系统目录,因此无法确定跨数据库查询的行为应如何。

contrib/dblink 允许使用函数调用进行跨数据库查询。当然,客户端也可以同时连接到不同的数据库并在客户端合并结果。

PostgreSQL 常见问题解答

是的,您可以使用 DBlink(仅限 postgresql)和 DBI-Link(允许外部跨数据库查询器)和 TDS_LInk(允许针对 MS SQL 服务器运行查询)。

我之前使用过DB-Link和TDS-link并取得了巨大成功。

如果性能很重要并且大多数查询都是只读的,我建议将数据复制到另一个数据库。虽然这看起来像是不必要的数据重复,但如果需要索引,它可能会有所帮助。

这可以通过简单的插入触发器来完成,该触发器依次调用 dblink 来更新另一个副本。还有成熟的复制选项(如 Slony),但这不是主题。

如果有人需要有关如何进行跨数据库查询的更复杂的示例,这里有一个清理 databasechangeloglock 每个拥有它的数据库上的表:

CREATE EXTENSION IF NOT EXISTS dblink;

DO 
$$
DECLARE database_name TEXT;
DECLARE conn_template TEXT;
DECLARE conn_string TEXT;
DECLARE table_exists Boolean;
BEGIN
    conn_template = 'user=myuser password=mypass dbname=';

    FOR database_name IN
        SELECT datname FROM pg_database
        WHERE datistemplate = false
    LOOP
        conn_string = conn_template || database_name;

        table_exists = (select table_exists_ from dblink(conn_string, '(select Count(*) > 0 from information_schema.tables where table_name = ''databasechangeloglock'')') as (table_exists_ Boolean));
        IF table_exists THEN
            perform dblink_exec(conn_string, 'delete from databasechangeloglock');
        END IF;     
    END LOOP;

END
$$
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top