在PLSQL中将变量与Substr一起使用

时间:2019-06-26 18:58:26

标签: oracle plsql types triggers substr

我正在尝试使用一个变量来设置substr命令的长度。 如果我明确设置为0.13,则代码可以正常运行,但是,我希望能够使用变量。

代码末尾附近是问题区域:

:new.DOCNO:= substr(:new.DESCRIP,0,15); -成功...但有限

:new.DOCNO:= substr(:new.DESCRIP,0,n_len); -失败

总体而言,代码正在寻找从文件名中找到数字模式并将其放置在另一列中的情况。

示例:HR_1000-0001_A这是一个文件。pdf

我尝试了各种数据类型:整数,数字等。 代码可以编译,但是在运行触发器时失败。

CREATE OR REPLACE TRIGGER set_doc_number
BEFORE UPDATE ON external_doc
FOR EACH ROW
WHEN (
    new.STATUS = 'Released'
    -- current document# is either '' or is ONLY a number
    AND (
            new.DOC_LIBRARY_ID = ''
            OR              
            REGEXP_LIKE(new.DOC_LIBRARY_ID,'(\d+)')
        )
    )
DECLARE 
    -- init variables
    b_update boolean;
    n_len number := 0;
BEGIN
    -- reset for each loop
    b_update := FALSE;

    -- check if criteria is met 

    -- AAA_####-####_AA
    IF b_update = FALSE AND REGEXP_LIKE(:new.DESCRIP,'([A-Z][A-Z][A-Z]_(\d{4})-(\d{4})_[A-Z])') THEN 
        b_update := TRUE;
        n_len := 15;
    END IF;
    -- AA_####-####_AA
    IF b_update = FALSE AND REGEXP_LIKE(:new.DESCRIP,'([A-Z][A-Z]_(\d{4})-(\d{4})_[A-Z])') THEN 
        b_update := TRUE;
        n_len := 14;
    END IF;
    -- AAA_####-####_A
    IF b_update = FALSE AND REGEXP_LIKE(:new.DESCRIP,'([A-Z][A-Z][A-Z]_(\d{4})-(\d{4})_[A-Z])') THEN 
        b_update := TRUE;
        n_len := 15;
    END IF;
    -- AA_####-####_A
    IF b_update = FALSE AND REGEXP_LIKE(:new.DESCRIP,'([A-Z][A-Z]_(\d{4})-(\d{4})_[A-Z])') THEN 
        b_update := TRUE;
        n_len := 14;
    END IF;
    -- AAA_####-####
    IF b_update = FALSE AND REGEXP_LIKE(:new.DESCRIP,'([A-Z][A-Z][A-Z]_(\d{4})-(\d{4}))') THEN  
        b_update := TRUE;
        n_len := 13;
    END IF;
    -- AA_####-####
    IF b_update = FALSE AND REGEXP_LIKE(:new.DESCRIP,'([A-Z][A-Z]_(\d{4})-(\d{4}))') THEN       
        b_update := TRUE;
        n_len := 12;
    END IF;

    -- can we update?
    IF b_update = TRUE THEN
        -- update
        :new.DOCNO := substr(:new.DESCRIP,0,n_len);
    END IF;
END;

1 个答案:

答案 0 :(得分:1)

我不确定为什么使用n_len会失败,这对我来说很好。 PL / SQL索引从1开始而不是0,但是如果使用0,它可以正常工作,所以这不是问题。

如果您要使用正则表达式功能,建议您仅使用regexp_substr

CREATE OR REPLACE TRIGGER set_doc_number
BEFORE UPDATE ON external_doc
FOR EACH ROW
WHEN (
    new.STATUS = 'Released'
    -- current document# is either '' or is ONLY a number
    AND (
            new.DOC_LIBRARY_ID = ''
            OR              
            REGEXP_LIKE(new.DOC_LIBRARY_ID,'(\d+)')
        )
    )
DECLARE 
    -- init variables
    v_docno varchar2(20);
BEGIN
    -- look for a str with (2-3 alpha)_####-####(optional underscore and 1-3 alpha)
    v_docno := regexp_substr(:new.DESCRIP,'[A-Z][A-Z][A-Z]?_\d{4}-\d{4}(_[A-Z][A-Z]?[A-Z]?)?');

    -- can we update?
    IF v_docno is not null THEN
        -- update
        :new.DOCNO := v_docno;
    END IF;
END;