1

我有问题如何使用 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();
4

1 回答 1

1

Postgres 8.2server_version_num引入了配置参数。根据文档:

添加新的配置参数 server_version_num (Greg Sabino Mullane)

这类似于 server_version,但它是一个整数,例如 80200。这允许应用程序更轻松地进行版本检查。

您的代码在 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。
  • 而是返回配置参数server_version,它也存在于 pg 8.1 中。
  • 我替换propertiesthe_column,假设这是另一个错误。
  • 不要使用大小写混合的名称。
  • 不要引用语言名称。使用LANGUAGE plpgsql,没有引号。

旁白:
显而易见的解决方案是将您的 Postgres 服务器升级到使用电力而不是蒸汽运行的版本。Postgres 8.1 是 10 年前编写的,并已在 2010 年 11 月达到 EOL。除此之外,至少更新到最后一个版本,即 8.1.23。

于 2015-02-24T02:26:03.780 回答