Pet*_*ter 3 postgresql types casting oid bytea
我正在尝试将bytea
列更改为具有类型oid
并仍然保留值。
我尝试过使用类似的查询:
ALTER TABLE mytable ADD COLUMN mycol_tmp oid;
UPDATE mytable SET mycol_tmp = CAST(mycol as oid);
ALTER TABLE mytable DROP COLUMN mycol;
ALTER TABLE mytable RENAME mycol_tmp TO mycol;
Run Code Online (Sandbox Code Playgroud)
但这只是给我一个错误:
ERROR: cannot cast type bytea to oid
Run Code Online (Sandbox Code Playgroud)
有什么方法可以实现我想要的吗?
Oid类型的列只是对实际存储在系统的pg_largeobject表中的二进制内容的引用。在存储方面,Oid为4字节整数。另一方面,bytea类型的列是实际内容。
要将字节转换为大对象,应使用大对象的类似于文件的API创建一个新的大对象:lo_create()获取新的OID,然后在写入模式下使用lo_open(),然后使用lo_write()进行写入或lowrite(),然后lo_close()。
仅通过转换就不能合理地做到这一点。
基本上,您需要以您选择的语言(至少一个支持大对象API,包括plpgsql)编写约10行代码来进行此转换。
Postgres 9.4为此添加了一个内置函数:
lo_from_bytea(loid oid, string bytea)
Run Code Online (Sandbox Code Playgroud)
从发行说明:
- 添加 SQL 函数以允许 [大对象读/写][12] 在任意偏移量 (Pavel Stehule)
对于旧版本,这比以前发布的更有效:
CREATE OR REPLACE FUNCTION blob_write(bytea)
RETURNS oid AS
$func$
DECLARE
loid oid := lo_create(0);
lfd int := lo_open(loid, 131072); -- = 2^17 = x2000
-- symbolic constant defined in the header file libpq/libpq-fs.h
-- #define INV_WRITE 0x00020000
BEGIN
PERFORM lowrite(lfd, $1);
PERFORM lo_close(lfd);
RETURN loid;
END
$func$ LANGUAGE plpgsql VOLATILE STRICT;
Run Code Online (Sandbox Code Playgroud)
该STRICT
修改是比手动处理空聪明。
更多在这个相关的答案:
归档时间: |
|
查看次数: |
6782 次 |
最近记录: |