在firebird中触发器更新生成器

时间:2016-03-11 09:15:23

标签: triggers generator firebird firebird2.5

我正在为Firebird数据库使用批量导入,这可能会对生成器产生问题,因为这些不一定会更新。

问题是,有没有办法直接在触发器中更新生成器的值?

我试过以下:

require(stringr)

string <- "Decreto Legislativo 6 marzo 1992, n. 248; G.U. n. 77 del 1° aprile 1992"

it_months <- c("gennaio","febbraio","marzo","aprile","maggio","giugno","luglio",
               "agosto","settembre","ottobre","novembre","dicembre")
grep_it_date <- paste0("\\d{1-2}(º?) (", paste(it_months, collapse="|") ,") \\d{4}$")

grepl(grep_it_date, string)
# [1] TRUE

dates_from_string <- str_extract_all(tolower(string), grep_it_date, simplify = TRUE)
# Error in stri_extract_all_regex(string, pattern, simplify = simplify,  : 
#                                   Error in {min,max} interval. (U_REGEX_BAD_INTERVAL)

我还尝试了begin if (new.ID is null) then begin new.ID = GEN_ID( mygenerator, 1); end else if (new.ID > GEN_ID( mygenerator, 0) ) then begin GEN_ID(mygenerator, new.ID - GEN(ID_mygenerator) ); end end ALTER SEQUENCE语句,但触发器中似乎没有接受...

有什么建议吗? 注意:我使用的是Firebird 2.5.4

1 个答案:

答案 0 :(得分:1)

我使用Firebird 2.5.5和Flamerobin生成的触发器(有一些小的改动)进行了测试。重要的区别似乎是使用赋值给局部变量:

CREATE TRIGGER WITH_GENERATOR_BI FOR WITH_GENERATOR ACTIVE
BEFORE INSERT POSITION 0
AS
DECLARE VARIABLE tmp BIGINT;
BEGIN
  IF (NEW.ID IS NULL) THEN
    NEW.ID = GEN_ID(GEN_WITH_GENERATOR_ID, 1);
  ELSE
  BEGIN
    tmp = GEN_ID(GEN_WITH_GENERATOR_ID, 0);
    if (tmp < new.ID) then
      tmp = GEN_ID(GEN_WITH_GENERATOR_ID, new.ID - tmp);
  END
END

可以修改现有代码以分配给临时变量(并使用GEN_ID的正确语法)。但是建议使用此代码,因为您的原始代码(带有修复)会产生竞争条件,如果并行另一个操作会使生成器值大于NEW.ID,则可能导致生成器反转。通过在检查和修改之前将GEN_ID(GEN_WITH_GENERATOR_ID, 0)的值分配给tmp变量,可以避免在第一个代码中出现这种竞争条件。

上述代码可能会出现竞争条件,导致生成器的值增加到不必要的值,但我认为很难避免这种情况。还要记住,当您回滚使用显式id完成的插入时,生成器值的更改是永久性的,不会回滚。