2017-09-15 137 views
1

我有一个INSERT触发器正则表达式检查,没有返回我的预期结果......但只有当在触发器中运行。从我的SQL编辑器运行时,它按预期工作。Postgres的正则表达式匹配不正确的触发器

失败触发代码(我加了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; 

这是抛出的异常(我预计tf):

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

如果我就跑这在我的SQL编辑器中直接:

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

它按预期返回false

的Postgres 9.6

更新:我试图孤立这个问题,但无法再现与下面的(如果这是显示问题,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; 
+0

我还有一个问题,它为什么't'? – revo

+0

t = true,f = false,除非我错过了什么 – pherris

+0

你确定't'表示是真的吗?或者你猜? – revo

回答

0

问题是添加触发器的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}$'