Postgresql PL/pgSQL匿名代码块

Postgresql PL/pgSQL匿名代码块,postgresql,plpgsql,Postgresql,Plpgsql,在PostgreSQL 9.0中,我有以下PLPGSQL匿名代码块: DO $$ DECLARE bigobject integer; BEGIN SELECT lo_creat(-1) INTO bigobject; ALTER LARGE OBJECT bigobject OWNER TO postgres; INSERT INTO files (id, "mountPoint", data, comment)

在PostgreSQL 9.0中,我有以下PLPGSQL匿名代码块:

DO $$
    DECLARE
        bigobject integer;
    BEGIN
        SELECT lo_creat(-1) INTO bigobject;
        ALTER LARGE OBJECT bigobject OWNER TO postgres;
        INSERT INTO files (id, "mountPoint", data, comment) VALUES (15, '/images/image.png', bigobject, 'image data');
        SET search_path = pg_catalog;
        SELECT pg_catalog.lo_open(bigobject, 131072);
        SELECT pg_catalog.lowrite(0, '\\x000001000100101010000000000028010000160000002800000010000000200000000100040');
        SELECT pg_catalog.lo_close(0);
        REVOKE ALL ON LARGE OBJECT bigobject FROM PUBLIC;
        REVOKE ALL ON LARGE OBJECT bigobject FROM postgres;
        GRANT ALL ON LARGE OBJECT bigobject TO postgres;
        GRANT ALL ON LARGE OBJECT bigobject TO "com.ektyn.eshops.myuser";
    END
$$;
但它失败了:

ERROR:  syntax error at or near "bigobject"
LINE 6:   ALTER LARGE OBJECT bigobject OWNER TO postgres;
                             ^

********** Error **********

ERROR: syntax error at or near "bigobject"
SQL state: 42601
Character: 103

我在代码中找不到错误。

改变大对象oid…
中必须有一个oid常量。尝试以下解决方法:

DO $$
    DECLARE
        bigobject integer;
    BEGIN
        SELECT lo_creat(-1) INTO bigobject;
        EXECUTE 'ALTER LARGE OBJECT ' || bigobject::text || ' OWNER TO postgres';
        ...
当然,这同样适用于授权和撤销。

除此之外,如果plpgsql代码中没有目标,则不能使用
SELECT
。在这些调用中替换为


旁白:使用
“com.ektyn.eshops.myuser”
作为角色名称是一个糟糕的想法。使用不必双引号的合法小写标识符。

这是因为PostgreSQL内部有两种完全不同的SQL语句——可计划的(
SELECT
INSERT
UPDATE
DELETE
)和不可计划的(其他所有)语句

只有可规划语句支持查询参数

PL/pgSQL使用查询参数实现对语句的变量替换,如
bigobject

因为不可规划语句不支持它们,所以不会执行替换。因此PL/pgSQL尝试按字面意思执行语句,就像您键入:

ALTER LARGE OBJECT bigobject OWNER TO postgres;
直接在
psql
提示符下。它不会将此检测为错误

要解决此问题,请使用
EXECUTE。。。格式
,例如

EXECUTE format('ALTER LARGE OBJECT %s OWNER TO postgres', bigobject);

请参阅。

我的回答肯定很有帮助,但klin解决了您问题中的主要问题。所以,答案应该是肯定的。