在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
我无法在代码中找到错误。
答案 0 :(得分:6)
ALTER LARGE OBJECT oid ...
中必须有 oid常量。试试这个解决方法:
DO $$
DECLARE
bigobject integer;
BEGIN
SELECT lo_creat(-1) INTO bigobject;
EXECUTE 'ALTER LARGE OBJECT ' || bigobject::text || ' OWNER TO postgres';
...
同样也适用于GRANT和REVOKE。
答案 1 :(得分:5)
除了@klin already cleared up之外,如果没有plpgsql代码中的目标,则不能使用SELECT
。在这些电话中将其替换为PERFORM
。
除此之外:使用"com.ektyn.eshops.myuser"
作为角色的名称是一个糟糕的主意。使用不必双引号的合法小写标识符。
答案 2 :(得分:4)
这是PostgreSQL内部有两种完全不同的SQL语句 - plannable (SELECT
,INSERT
,UPDATE
和DELETE
)和 unplannable (其他所有)语句。
只有plannable语句支持查询参数。
PL / pgSQL使用查询参数在bigobject
等语句中实现变量替换。
因为非plannable语句不支持它们,所以不执行替换。所以PL / pgSQL尝试按字面意思执行语句,就好像你输入了一样:
ALTER LARGE OBJECT bigobject OWNER TO postgres;
直接在psql
提示符下。它不会将此检测为错误。
要解决此问题,请使用EXECUTE ... FORMAT
,例如
EXECUTE format('ALTER LARGE OBJECT %s OWNER TO postgres', bigobject);