将查询从 Firebird 转换为 PostgreSQL
Translating query from Firebird to PostgreSQL
我有一个 Firebird 查询,我应该将其重写为 PostgreSQL 代码。
SELECT TRIM(RL.RDB$RELATION_NAME), TRIM(FR.RDB$FIELD_NAME), FS.RDB$FIELD_TYPE
FROM RDB$RELATIONS RL
LEFT OUTER JOIN RDB$RELATION_FIELDS FR ON FR.RDB$RELATION_NAME = RL.RDB$RELATION_NAME
LEFT OUTER JOIN RDB$FIELDS FS ON FS.RDB$FIELD_NAME = FR.RDB$FIELD_SOURCE
WHERE (RL.RDB$VIEW_BLR IS NULL)
ORDER BY RL.RDB$RELATION_NAME, FR.RDB$FIELD_NAME
我理解 SQL,但不知道如何使用此系统表,如 RDB$RELATIONS
等。如果有人帮助我,那将是非常好的,但即使是一些链接这个表解释就OK了。
这段查询是用 C++ 代码编写的,当我尝试执行此操作时:
pqxx::connection conn(serverAddress.str());
pqxx::work trans(conn);
pqxx::result res(trans.exec(/*there is this SQL query*/));//and there is a mistake
它写道:
RDB$RELATIONS doesn't exist.
我认为您正在寻找 information_schema
。
表格列于此处:https://www.postgresql.org/docs/current/static/information-schema.html
例如,您可以使用:
select * from information_schema.tables;
select * from information_schema.columns;
Postgres 有另一种存储系统内容信息的方法。这叫做System Catalogs.
在 Firebird 中,您的查询基本上 return 在每个架构中 table 的每一列都有一行,并带有一个映射到字段数据类型的附加整数列。
在 pg_catalog
模式中使用系统 tables 的 Postgres 中,使用此查询可以实现类似的事情:
SELECT
TRIM(c.relname) AS table_name, TRIM(a.attname) AS column_name, a.atttypid AS field_type
FROM pg_class c
LEFT JOIN pg_attribute a ON
c.oid = a.attrelid
AND a.attnum > 0 -- only ordinary columns, without system ones
WHERE c.relkind = 'r' -- only tables
ORDER BY 1,2
以上查询也执行 return 系统目录。如果您想 排除 它们,您需要将另一个 JOIN 添加到 pg_namespace
和一个带有 pg_namespace.nspname <> 'pg_catalog'
的 where 子句,因为这是系统目录所在的架构已存储。
如果您还想查看数据类型名称而不是它们的代表编号,请将 JOIN 添加到 pg_type
。
信息模式 由视图集合组成。在大多数情况下,您不需要视图背后的整个 SQL 查询,因此使用系统 tables 将为您提供更好的性能。不过,您可以检查视图定义,只是为了让您开始了解用于形成输出的 tables 和条件。
我有一个 Firebird 查询,我应该将其重写为 PostgreSQL 代码。
SELECT TRIM(RL.RDB$RELATION_NAME), TRIM(FR.RDB$FIELD_NAME), FS.RDB$FIELD_TYPE
FROM RDB$RELATIONS RL
LEFT OUTER JOIN RDB$RELATION_FIELDS FR ON FR.RDB$RELATION_NAME = RL.RDB$RELATION_NAME
LEFT OUTER JOIN RDB$FIELDS FS ON FS.RDB$FIELD_NAME = FR.RDB$FIELD_SOURCE
WHERE (RL.RDB$VIEW_BLR IS NULL)
ORDER BY RL.RDB$RELATION_NAME, FR.RDB$FIELD_NAME
我理解 SQL,但不知道如何使用此系统表,如 RDB$RELATIONS
等。如果有人帮助我,那将是非常好的,但即使是一些链接这个表解释就OK了。
这段查询是用 C++ 代码编写的,当我尝试执行此操作时:
pqxx::connection conn(serverAddress.str());
pqxx::work trans(conn);
pqxx::result res(trans.exec(/*there is this SQL query*/));//and there is a mistake
它写道:
RDB$RELATIONS doesn't exist.
我认为您正在寻找 information_schema
。
表格列于此处:https://www.postgresql.org/docs/current/static/information-schema.html
例如,您可以使用:
select * from information_schema.tables;
select * from information_schema.columns;
Postgres 有另一种存储系统内容信息的方法。这叫做System Catalogs.
在 Firebird 中,您的查询基本上 return 在每个架构中 table 的每一列都有一行,并带有一个映射到字段数据类型的附加整数列。
在 pg_catalog
模式中使用系统 tables 的 Postgres 中,使用此查询可以实现类似的事情:
SELECT
TRIM(c.relname) AS table_name, TRIM(a.attname) AS column_name, a.atttypid AS field_type
FROM pg_class c
LEFT JOIN pg_attribute a ON
c.oid = a.attrelid
AND a.attnum > 0 -- only ordinary columns, without system ones
WHERE c.relkind = 'r' -- only tables
ORDER BY 1,2
以上查询也执行 return 系统目录。如果您想 排除 它们,您需要将另一个 JOIN 添加到 pg_namespace
和一个带有 pg_namespace.nspname <> 'pg_catalog'
的 where 子句,因为这是系统目录所在的架构已存储。
如果您还想查看数据类型名称而不是它们的代表编号,请将 JOIN 添加到 pg_type
。
信息模式 由视图集合组成。在大多数情况下,您不需要视图背后的整个 SQL 查询,因此使用系统 tables 将为您提供更好的性能。不过,您可以检查视图定义,只是为了让您开始了解用于形成输出的 tables 和条件。