【问题标题】:Rule to validate a comma-separated field PLSQL验证逗号分隔字段 PLSQL 的规则
【发布时间】:2020-03-09 12:26:24
【问题描述】:

我正在开发一个程序并在验证用逗号分隔的字段的步骤处停止。

我需要验证该字段中有两条以逗号分隔的记录,如果存在,请通过删除条目记录并保留另一条来更新该字段。 如果有超过 2 条记录,请检查哪条记录是输入记录并验证它是在逗号的左侧还是右侧以执行字段更新并将其他记录保留在那里。

我将演示下面的字段:

        CONCIL
RECORDa,RECORDb,RECORDc

这是我目前所开发的:

CREATE OR REPLACE PROCEDURE SP_CANCEL (
    P_COD_MATRIZ INT,
    P_CONCIL IN TB_EDIEXT_PERFIL.COD_MATRIZ%TYPE,
    P_ID_CONCIL INT
)
IS  
    V_VIRGULA INT;
    V_RIGHT VARCHAR2(100);

BEGIN 

    IF P_ID_CONCIL IS NOT NULL
    THEN
    DELETE FROM TB_EDIEXT_PERFIL_MBX WHERE ID_MBX = P_ID_CONCIL AND ID_PERFIL = (SELECT ID FROM TB_EDIEXT_PERFIL 
        WHERE COD_MATRIZ = P_COD_MATRIZ);
    END IF;

    IF TB_EDIEXT_PERFIL.CD = 1 THEN
    DELETE FROM TB_EDIEXT_PERFIL_CD WHERE ID_CD = P_ID_CONCIL AND ID_PERFIL = (SELECT ID FROM TB_EDIEXT_PERFIL 
        WHERE COD_MATRIZ = P_COD_MATRIZ);
    UPDATE TB_EDIEXT_PERFIL SET CD = 0 WHERE COD_MATRIZ = P_COD_MATRIZ;

    ELSIF TB_EDIEXT_PERFIL_SFTP = 1 THEN
    DELETE FROM TB_EDIEXT_PERFIL_SFTP WHERE ID_SFTP = P_ID_CONCIL AND ID_PERFIL = (SELECT ID FROM TB_EDIEXT_PERFIL 
        WHERE COD_MATRIZ = P_COD_MATRIZ);
    UPDATE TB_EDIEXT_PERFIL SET SFTP = 0 WHERE COD_MATRIZ = P_COD_MATRIZ;
    END IF;

    SELECT REGEXP_COUNT((SELECT TB_EDIEXT_PERFIL.CONCIL 
    FROM TB_EDIEXT_PERFIL 
        WHERE COD_MATRIZ = P_COD_MATRIZ), ',') INTO V_VIRGULA FROM DUAL;

    IF V_VIRGULA = 0 THEN
    UPDATE TB_EDIEXT_PERFIL SET CONCIL = 'EC' WHERE COD_MATRIZ = P_COD_MATRIZ;
    END IF;

    SELECT 
    SUBSTR(TO_CHAR((SELECT TB_EDIEXT_PERFIL.CONCIL 
    FROM TB_EDIEXT_PERFIL 
        WHERE COD_MATRIZ = P_COD_MATRIZ)), INSTR(TO_CHAR((SELECT TB_EDIEXT_PERFIL.CONCIL 
    FROM TB_EDIEXT_PERFIL 
        WHERE COD_MATRIZ = P_COD_MATRIZ)), ',') +1) 
    INTO V_RIGHT FROM DUAL;

-- Here is the rule for validating the field separated by commas  

END;
/

记住: 该字段最多可以包含三个记录。 并在声明 P_CONCIL 签入时删除记录。

手动例程:

DELETE FROM TB_EDIEXT_PERFIL_MBX where ID_PERFIL = (SELECT ID FROM TB_EDIEXT_PERFIL           WHERE     COD_MATRIZ = '0000000000')   AND ID = '0000';
DELETE FROM TB_EDIEXT_PERFIL_SFTP         WHERE ID_PERFIL = (SELECT ID FROM TB_EDIEXT_PERFIL  WHERE     COD_MATRIZ = '0000000000')   AND ID = '0000';
UPDATE TB_EDIEXT_PERFIL SET SFTP = 0      WHERE                                                         COD_MATRIZ = '0000000000';
UPDATE TB_EDIEXT_PERFIL SET CONCIL = 'EC' WHERE                                                         COD_MATRIZ = '0000000000';
SELECT ID, COD_MATRIZ, CONCIL, CD, SFTP FROM TB_EDIEXT_PERFIL                                 WHERE     COD_MATRIZ = '0000000000';
SELECT * FROM TB_EDIEXT_PERFIL_MBX  where ID_PERFIL =  (SELECT ID FROM TB_EDIEXT_PERFIL       WHERE     COD_MATRIZ = '0000000000');
SELECT * FROM TB_EDIEXT_PERFIL_SFTP  where ID_PERFIL = (SELECT ID FROM TB_EDIEXT_PERFIL       WHERE     COD_MATRIZ = '0000000000');

谢谢你,我期待得到很大的帮助!

【问题讨论】:

  • 如果总是有两个字段,那么不要在单个列中使用逗号分隔的字符串;使用适当数据类型的两列。
  • 好的,但是定义列的是数据库管理员。我目前无事可做创建或更改表。
  • 你能(以外交方式)告诉 DBA 他们错了吗?使用逗号分隔的字符串来存储成对的值是一种复杂且越来越难以维护的解决方案的秘诀,如果你可以将将相同的值放入具有明确定义的数据类型的两列中。保持简单!
  • 我已经尝试并设计了此类基础架构的解决方案,但我仍然没有反馈。我知道我要求的不是正常形式的数据库,但我需要暂时的帮助来制定此规则,以消除手动完成的任务,从而消除错误。
  • 你继续发布更多代码;请edit您的问题并发布DATA!您的基础表的结构是什么?这些表的行中有哪些值?当您调用该函数时,您使用什么输入值?您希望这些表中的值如何变化(请用英语而不是通过更多代码描述此过程)?请假设我们不理解您在说什么(因为很可能我们不理解)并且只用代码(或关于“矩阵取消”或您未描述的表和列)进行讨论会造成混淆我们。

标签: sql database oracle plsql


【解决方案1】:

我不明白您要对代码做什么,因为您没有在示例数据之前/之后发布。你怎么称呼这个过程?

但这应该可以很好地回答您的问题,以便您弄清楚其余的问题。

-- example data
create table TB_EDIEXT_PERFIL (concil varchar2(400));
insert into TB_EDIEXT_PERFIL values ('RECORDa,RECORDb,RECORDc');

declare
    v_left varchar2(100);
    v_center varchar2(100);
    v_right varchar2(100);
begin
    for r in (
      select level as lev, regexp_substr(TB_EDIEXT_PERFIL.CONCIL, '(.*?)(,|$)', 1, level, null, 1) as val
      from TB_EDIEXT_PERFIL
      connect by level <= 3)
    loop
        if r.lev = 1 then
            v_left = r.val;
        elsif r.lev = 2 then
            v_center = r.val;
        elsif r.lev = 3 then
            v_right = r.val;
        end if;
    end loop;

    -- show variables
    dbms_output.print_line(v_left);
    dbms_output.print_line(v_center);
    dbms_output.print_line(v_right);
end;
/

如果其中一个值为空白,例如RECORDa,,RECORDc,则对应的变量(如v_center)将为空。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-30
    • 1970-01-01
    • 1970-01-01
    • 2011-03-28
    • 1970-01-01
    • 2021-08-26
    相关资源
    最近更新 更多