使用 plpgsql 将列 bytea 更改为各种版本的 Postgres 中的文本
Alter column bytea to text in various versions of Postgres with plpgsql
我在如何使用 plpgsql 转换列时遇到问题 (bytea
-> text
)。我编写的函数适用于某些数据库,但不适用于其他数据库。我不知道如何解决它。
使用 8.0 - 9.3 的数据库;此错误适用于 8.1.19。
我收到了:
ERROR: column "the_column" cannot be cast to type "text"
CONTEXT: SQL statement "ALTER TABLE the_table ALTER COLUMN the_column TYPE text"
PL/pgSQL function "byteatotext" line 11 at execute statement
我的函数:
CREATE OR REPLACE FUNCTION byteaToText()
RETURNS text AS
$BODY$
DECLARE
ver int;
BEGIN
SELECT into ver (select setting from pg_settings where name='server_version_num') as test;
IF ver < 80200 THEN
EXECUTE 'ALTER TABLE the_table ALTER COLUMN the_column TYPE text USING ENCODE(properties, \'escape\'))';
RETURN ver;
ELSE
EXECUTE 'ALTER TABLE the_table ALTER COLUMN the_column TYPE text';
RETURN ver;
END IF;
RETURN 'error';
END;
$BODY$
LANGUAGE 'plpgsql' VOLATILE;
select byteaToText();
配置参数 server_version_num
是随 Postgres 8.2 引入的。 Per documentation:
Add new configuration parameter server_version_num (Greg Sabino Mullane)
This is like server_version, but is an integer, e.g. 80200. This
allows applications to make version checks more easily.
您的代码在 pg 8.1 中找不到不存在的参数并且没有分配给 ver
,因此它保持为 NULL 并且控制最终在 ELSE
分支中 - 这也被指示在错误消息中:
ERROR: column "the_column" cannot be cast to type "text"
CONTEXT: SQL statement "ALTER TABLE the_table ALTER COLUMN the_column TYPE text"
PL/pgSQL function "byteatotext" line 11 at execute statement
将函数重写为:
CREATE OR REPLACE FUNCTION bytea_to_text()
RETURNS text AS
$func$
BEGIN
-- the config param was introduced with version 8.2
PERFORM 1 FROM pg_settings WHERE name = 'server_version_num';
IF FOUND THEN -- version >= 8.2
EXECUTE 'ALTER TABLE the_table ALTER COLUMN the_column TYPE text';
ELSE
EXECUTE 'ALTER TABLE the_table ALTER COLUMN the_column TYPE text USING encode(the_column, ''escape''))';
END IF;
RETURN (SELECT setting FROM pg_settings WHERE name = 'server_version');
END
$func$ LANGUAGE plpgsql;
备注
- 未经 Postgres 8.1 测试,没有人再使用那么旧的 Postgres。
- Return 配置参数
server_version
相反,它也存在于 pg 8.1 中。
- 我将
properties
替换为 the_column
,假设这是另一个错误。
- 不要使用大小写混合的名称。
- 不要引用语言名称。使用
LANGUAGE plpgsql
,没有引号。
旁白:
显而易见的解决方案是将您的 Postgres 服务器升级到 运行 电力版本,而不是蒸汽版本。 Postgres 8.1 是 10 年前编写的,已于 2010 年 11 月停产。除此之外,至少更新到最后一个版本,即 8.1.23。
我在如何使用 plpgsql 转换列时遇到问题 (bytea
-> text
)。我编写的函数适用于某些数据库,但不适用于其他数据库。我不知道如何解决它。
使用 8.0 - 9.3 的数据库;此错误适用于 8.1.19。
我收到了:
ERROR: column "the_column" cannot be cast to type "text" CONTEXT: SQL statement "ALTER TABLE the_table ALTER COLUMN the_column TYPE text" PL/pgSQL function "byteatotext" line 11 at execute statement
我的函数:
CREATE OR REPLACE FUNCTION byteaToText()
RETURNS text AS
$BODY$
DECLARE
ver int;
BEGIN
SELECT into ver (select setting from pg_settings where name='server_version_num') as test;
IF ver < 80200 THEN
EXECUTE 'ALTER TABLE the_table ALTER COLUMN the_column TYPE text USING ENCODE(properties, \'escape\'))';
RETURN ver;
ELSE
EXECUTE 'ALTER TABLE the_table ALTER COLUMN the_column TYPE text';
RETURN ver;
END IF;
RETURN 'error';
END;
$BODY$
LANGUAGE 'plpgsql' VOLATILE;
select byteaToText();
配置参数 server_version_num
是随 Postgres 8.2 引入的。 Per documentation:
Add new configuration parameter server_version_num (Greg Sabino Mullane)
This is like server_version, but is an integer, e.g. 80200. This allows applications to make version checks more easily.
您的代码在 pg 8.1 中找不到不存在的参数并且没有分配给 ver
,因此它保持为 NULL 并且控制最终在 ELSE
分支中 - 这也被指示在错误消息中:
ERROR: column "the_column" cannot be cast to type "text" CONTEXT: SQL statement "ALTER TABLE the_table ALTER COLUMN the_column TYPE text" PL/pgSQL function "byteatotext" line 11 at execute statement
将函数重写为:
CREATE OR REPLACE FUNCTION bytea_to_text()
RETURNS text AS
$func$
BEGIN
-- the config param was introduced with version 8.2
PERFORM 1 FROM pg_settings WHERE name = 'server_version_num';
IF FOUND THEN -- version >= 8.2
EXECUTE 'ALTER TABLE the_table ALTER COLUMN the_column TYPE text';
ELSE
EXECUTE 'ALTER TABLE the_table ALTER COLUMN the_column TYPE text USING encode(the_column, ''escape''))';
END IF;
RETURN (SELECT setting FROM pg_settings WHERE name = 'server_version');
END
$func$ LANGUAGE plpgsql;
备注
- 未经 Postgres 8.1 测试,没有人再使用那么旧的 Postgres。
- Return 配置参数
server_version
相反,它也存在于 pg 8.1 中。 - 我将
properties
替换为the_column
,假设这是另一个错误。 - 不要使用大小写混合的名称。
- 不要引用语言名称。使用
LANGUAGE plpgsql
,没有引号。
旁白:
显而易见的解决方案是将您的 Postgres 服务器升级到 运行 电力版本,而不是蒸汽版本。 Postgres 8.1 是 10 年前编写的,已于 2010 年 11 月停产。除此之外,至少更新到最后一个版本,即 8.1.23。