代码之家  ›  专栏  ›  技术社区  ›  pherris

触发器中的Postgres正则表达式匹配不正确

  •  1
  • pherris  · 技术社区  · 7 年前

    我有一个带有正则表达式检查的插入触发器,它没有返回我的预期结果。。。但是 在触发器中运行时。当从我的SQL编辑器运行时,它按预期工作。

    失败的触发器代码(我添加了 RAISE IF 以下声明):

    RAISE EXCEPTION 'postal_code regex check %', '55555' !~* '^\d{5}$';
    IF NEW.postal_code !~* '^\d{5}$' THEN
      errors := ARRAY_APPEND(errors, 'Postal code format is invalid.');
    END IF;
    

    这是抛出的异常(我希望 t f ):

     # --- Caused by: ---
     # PG::RaiseException:
     #   ERROR:  postal_code regex check t
    

    如果我直接在SQL编辑器中运行它:

    select '55555' !~* '^\d{5}$';
    

    它回来了 false 正如所料。

    select count(*) 应返回0,但返回1):

    DROP TABLE IF EXISTS my_table;
    
    CREATE TABLE my_table (
        postal_code varchar
    );
    
    CREATE OR REPLACE FUNCTION validate_postal_code() RETURNS trigger
        LANGUAGE plpgsql
        AS $_$
            DECLARE
    
            BEGIN
              IF NEW.postal_code !~* '^\d{5}$' THEN
                RETURN false;
              END IF;
    
              RETURN NEW;
            END;
          $_$;
    
    DROP TRIGGER IF EXISTS validate_postal_code_trigger on my_table;
    CREATE TRIGGER validate_postal_code_trigger BEFORE INSERT ON my_table FOR EACH ROW EXECUTE PROCEDURE validate_postal_code();
    
    insert into my_table values ('55555');
    
    select count(*) from my_table;
    
    1 回复  |  直到 7 年前
        1
  •  0
  •   pherris    7 年前

    问题是Rails迁移添加触发器时从正则表达式中去掉了反斜杠。

    在迁移中使用以下语法:

    sql = <<-SQL
      CREATE OR REPLACE FUNCTION validate_postal_code() RETURNS trigger
        LANGUAGE plpgsql
        AS $$
            DECLARE
    
            BEGIN
              IF NEW.postal_code !~ '^\d{5}$' THEN
                RAISE EXCEPTION 'Debug--> postal_code regex check %, %, %', NEW.postal_code !~* '^\d{5}$', TG_OP, NEW.postal_code;
              END IF;
              RETURN NEW;
            END;
          $$;
    
      DROP TRIGGER IF EXISTS validate_postal_code_trigger on my_table;
      CREATE TRIGGER validate_postal_code_trigger BEFORE INSERT ON my_table 
      FOR EACH ROW EXECUTE PROCEDURE validate_postal_code();
    SQL
    
    execute sql
    

    在Rails迁移中,我去掉了正则表达式中的反斜杠。应用于数据库的实际正则表达式是 '^d{5}$' (缺少反斜杠)而不是 '^\d{5}$'