35.4. 服务器端功能

Table 35.1中列出了专门为从 SQL 处理大型对象而定制的服务器端功能。

表 35.1 面向 SQL 的大对象函数

FunctionReturn TypeDescriptionExampleResult
lo_from_bytea(loid oid, string bytea)oid创建一个大对象并在其中存储数据,并返回其 OID。传递0以使系统选择一个 OID。lo_from_bytea(0, '\xffffff00')24528
lo_put(loid oid, offset bigint, str bytea)void以给定的偏移量写入数据。lo_put(24528, 1, '\xaa')
lo_get(loid oid [, from bigint, for int])bytea提取内容或其子字符串。lo_get(24528, 0, 3)\xffaaff

还有其他服务器端功能,它们与前面描述的每个 Client 端功能相对应。实际上,在大多数情况下,Client 端功能只是与等效服务器端功能的接口。通过 SQL 命令调用同样方便的是lo_creat lo_createlo_unlink lo_import lo_export 。以下是其用法示例:

CREATE TABLE image (
    name            text,
    raster          oid
);

SELECT lo_creat(-1);       -- returns OID of new, empty large object

SELECT lo_create(43213);   -- attempts to create large object with OID 43213

SELECT lo_unlink(173454);  -- deletes large object with OID 173454

INSERT INTO image (name, raster)
    VALUES ('beautiful image', lo_import('/etc/motd'));

INSERT INTO image (name, raster)  -- same as above, but specify OID to use
    VALUES ('beautiful image', lo_import('/etc/motd', 68583));

SELECT lo_export(image.raster, '/tmp/motd') FROM image
    WHERE name = 'beautiful image';

服务器端lo_importlo_export函数的行为与其 Client 端类似物有很大不同。这两个函数使用数据库拥有的用户的权限在服务器的文件系统中读写文件。因此,默认情况下,它们的使用仅限于超级用户。相反,Client 端导入和导出功能使用 Client 端程序的权限读取和写入 Client 端文件系统中的文件。Client 端功能不需要任何数据库特权,只有读取或写入有问题的大对象的特权除外。

Caution

非超级用户可以GRANT使用服务器端lo_importlo_export函数,但是需要仔细考虑安全隐患。具有这种特权的恶意用户可以很容易地使它们成为超级用户(例如,通过重写服务器配置文件),或者可以攻击服务器的文件系统的其余部分而无需费心地获取数据库超级用户特权。 *因此,对具有这种特权的角色的访问必须与对超级用户角色的访问同样谨慎地保护。具有完全的超级用户特权,因为这有助于减少意外错误造成损害的风险。

lo_readlo_write的功能也可以通过服务器端调用来使用,但是服务器端函数的名称与 Client 端接口的不同之处在于它们不包含下划线。您必须将这些函数称为loreadlowrite