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

如何创建支持多表多字段的通用PostgreSQL标准化ID触发器函数

Generic Trigger Function for Uppercasing Column Values Across Multiple Tables

Great question! Instead of cluttering your function with table-specific IF/ELSEIF checks, we can build a fully generic trigger function that adapts to any table by accepting the target column name as an argument when creating the trigger. This uses PostgreSQL's built-in trigger context variables and JSONB to dynamically modify the correct column without hardcoding table logic.

Modified Generic Function

Here's the updated function that works with any table and text-based column:

CREATE OR REPLACE FUNCTION std_user_id()
RETURNS trigger AS $$
DECLARE
    modified_value text;
    column_exists boolean;
BEGIN
    -- Ensure a column name was provided when creating the trigger
    IF TG_ARGV[0] IS NULL THEN
        RAISE EXCEPTION 'Trigger requires a column name as an argument (e.g., EXECUTE FUNCTION std_user_id(''login_id''))';
    END IF;

    -- Validate the column exists in the target table (optional but recommended)
    SELECT EXISTS (
        SELECT 1
        FROM information_schema.columns
        WHERE table_schema = TG_TABLE_SCHEMA
          AND table_name = TG_TABLE_NAME
          AND column_name = TG_ARGV[0]
    ) INTO column_exists;

    IF NOT column_exists THEN
        RAISE EXCEPTION 'Column "%" does not exist in table "%"."%"', TG_ARGV[0], TG_TABLE_SCHEMA, TG_TABLE_NAME;
    END IF;

    -- Trim and uppercase the column value
    modified_value := UPPER(TRIM(to_jsonb(NEW) ->> TG_ARGV[0]));

    -- Update the NEW record with the modified value (works for any table type)
    NEW := jsonb_set(to_jsonb(NEW), ARRAY[TG_ARGV[0]], to_jsonb(modified_value))::pg_typeof(NEW);

    RETURN NEW;
END;
$$ LANGUAGE plpgsql;

How to Use It for Different Tables

When creating triggers, simply pass the name of the column you want to normalize as an argument to the function:

For the users table (targeting login_id):

DROP TRIGGER IF EXISTS users_std_user_id ON users;
CREATE TRIGGER users_std_user_id
BEFORE INSERT OR UPDATE ON users
FOR EACH ROW
EXECUTE FUNCTION std_user_id('login_id');

For the user_roles table (targeting user_id):

DROP TRIGGER IF EXISTS user_roles_std_user_id ON user_roles;
CREATE TRIGGER user_roles_std_user_id
BEFORE INSERT OR UPDATE ON user_roles
FOR EACH ROW
EXECUTE FUNCTION std_user_id('user_id');

Key Benefits

  • No table-specific logic: Works with any table that has a text-based column you want to normalize.
  • Flexible: Add triggers for new tables by just specifying the column name—no function changes needed.
  • Safe: Includes validation to ensure the specified column exists, preventing unexpected runtime errors.

Notes

  • This assumes the target column is a text-based type (like text, varchar). For non-text columns, you’d need to add a type check to avoid conversion errors.
  • The JSONB approach is clean and avoids complex dynamic SQL, making the function easy to maintain and debug.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 08:10:31