You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在PostgreSQL的MY_ENCRYPT函数中获取MYTYPE列的TYPMOD值?

在PostgreSQL函数中获取自定义类型的TYPMOD值

核心结论

默认情况下,PostgreSQL的函数无法直接从传入的自定义类型实例中获取列定义时的TYPMOD(即你示例中的X值),因为TYPMOD是列级别的元数据属性,不属于类型实例本身的内容。不过可以通过以下两种方式实现需求:


方法1:将TYPMOD作为额外参数传入加密函数

修改MY_ENCRYPT函数,增加一个整数参数用于接收TYPMOD值:

CREATE OR REPLACE FUNCTION MY_ENCRYPT(val mytype, typmod integer) 
RETURNS mytype AS $$
BEGIN
  -- 在这里使用typmod值检查加密后的数据大小
  IF 加密后的数据长度 > (typmod - 加密开销) THEN
    RAISE EXCEPTION '加密后数据超出允许范围';
  END IF;
  -- 执行3DES加密逻辑
  RETURN 加密结果;
END;
$$ LANGUAGE plpgsql;

调用函数时,先从系统表中查询目标列的TYPMOD(注意:部分类型的atttypmod会有固定偏移,需根据MYTYPE的定义调整):

-- 查询t0表c0列的真实typmod值
SELECT atttypmod - 4 FROM pg_attribute 
WHERE attrelid = 't0'::regclass AND attname = 'c0';

-- 调用加密函数时传入该值
UPDATE t0 SET c0 = MY_ENCRYPT(c0, 80) WHERE ...;

方法2:通过触发器自动传递TYPMOD

如果希望在数据写入时自动完成检查和加密,可以创建触发器,在触发器中获取列的TYPMOD并调用加密函数:

CREATE OR REPLACE FUNCTION t0_encrypt_trigger() 
RETURNS trigger AS $$
DECLARE
  col_typmod integer;
BEGIN
  -- 获取当前列的typmod
  SELECT atttypmod - 4 INTO col_typmod 
  FROM pg_attribute 
  WHERE attrelid = TG_RELID AND attname = 'c0';
  
  -- 调用加密函数并传入typmod
  NEW.c0 = MY_ENCRYPT(NEW.c0, col_typmod);
  RETURN NEW;
END;
$$ LANGUAGE plpgsql;

-- 绑定触发器到t0表
CREATE TRIGGER t0_encrypt_trigger
BEFORE INSERT OR UPDATE ON t0
FOR EACH ROW EXECUTE FUNCTION t0_encrypt_trigger();

关键说明

  • 系统表pg_attribute中的atttypmod字段,对于部分内置类型(如varchar)会包含固定偏移(比如varchar(n)的atttypmod是n+4),你需要根据自己定义的MYTYPE的实现逻辑,调整获取到的atttypmod值,得到真实的X。
  • 由于你的MYTYPE是通用类型,无法修改其结构嵌入TYPMOD,上述两种方法都是在类型外部传递元数据,符合你的需求。

内容的提问来源于stack exchange,提问作者TheBadCat

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 05:24:56