我正在为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
答案 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完成的插入时,生成器值的更改是永久性的,不会回滚。