PL SQL 替代嵌套异常

Posted

技术标签:

【中文标题】PL SQL 替代嵌套异常【英文标题】:PL SQL alternative to nested exceptions 【发布时间】:2013-09-13 18:12:11 【问题描述】:

我想知道是否有任何替代方法可以解决这种逻辑,而不使用嵌套异常。这是返回整数值的函数的一部分。谢谢。

IF PNOMTARIFA = 'DEPOSITO' 
THEN
   BEGIN
      SELECT CL.ID_TIPO_CONT_LINEA, 
             CL.NOMBRE_TIPO_CONTENEDOR, 
             TC.DEPOSITO ,
             L.NOMBRE
        INTO idcontlinea, 
             tcontenedor, 
             deposito, 
             vlinea
        FROM TIPO_CONT TE, 
             TIPO_CONT_LINEA CL, 
             TARIFAS_DEPOSITO TC, 
             LINEAS L
       WHERE TE.ID_TIPO_CONT = CL.ID_TIPO_CONTENEDOR
         AND CL.ID_TIPO_CONT_LINEA = TC.ID_TIPO_CONT_LINEA
         AND CL.LINEA = L.LINEA
         AND TE.ID_TIPO_CONT = PTIPO_CONT
         AND CL.LINEA = PLINEA
         AND TC.NIT = PNITCLIENTE
         AND TC.BL = PNUMBL
         AND TC.VIGENCIA_DEPOSITO >= trunc(SYSDATE);

    EXCEPTION 
       WHEN OTHERS THEN 
         BEGIN
            SELECT CL.ID_TIPO_CONT_LINEA, 
                   CL.NOMBRE_TIPO_CONTENEDOR, 
                   TC.DEPOSITO ,
                   L.NOMBRE
              INTO idcontlinea, 
                   tcontenedor, 
                   deposito, 
                   vlinea
              FROM TIPO_CONT TE, 
                   TIPO_CONT_LINEA CL, 
                   TARIFAS_DEPOSITO TC, 
                   LINEAS L
             WHERE TE.ID_TIPO_CONT = CL.ID_TIPO_CONTENEDOR
               AND CL.ID_TIPO_CONT_LINEA = TC.ID_TIPO_CONT_LINEA
               AND CL.LINEA = L.LINEA
               AND TE.ID_TIPO_CONT = PTIPO_CONT
               AND CL.LINEA = PLINEA
               AND TC.NIT = PNITCLIENTE
               AND TC.PUERTO_CARGUE = PPTOCARGUE
               AND TC.PUERTO_DESCARGUE = PPTODESCARGUE
               AND PCLIENTEEXT LIKE '%'||TC.CLIENTE_EXT||'%'
               AND TC.BL IS NULL
               AND TC.VIGENCIA_DEPOSITO >= trunc(SYSDATE);
        EXCEPTION 
           WHEN OTHERS THEN
             BEGIN
                SELECT CL.ID_TIPO_CONT_LINEA, 
                       CL.NOMBRE_TIPO_CONTENEDOR, 
                       TC.DEPOSITO , 
                       L.NOMBRE
                  INTO idcontlinea, 
                       tcontenedor, 
                       deposito, 
                       vlinea
                  FROM TIPO_CONT TE, 
                       TIPO_CONT_LINEA CL, 
                       TARIFAS_DEPOSITO TC, 
                       LINEAS L
                 WHERE TE.ID_TIPO_CONT = CL.ID_TIPO_CONTENEDOR
                   AND CL.ID_TIPO_CONT_LINEA = TC.ID_TIPO_CONT_LINEA
                   AND CL.LINEA = L.LINEA
                   AND TE.ID_TIPO_CONT = PTIPO_CONT
                   AND CL.LINEA = PLINEA
                   AND TC.NIT = PNITCLIENTE
                   AND TC.PUERTO_CARGUE = PPTOCARGUE
                   AND TC.PUERTO_DESCARGUE = PPTODESCARGUE
                   AND TC.CLIENTE_EXT IS NULL
                   AND TC.BL IS NULL
                   AND TC.VIGENCIA_DEPOSITO >= trunc(SYSDATE);
            EXCEPTION WHEN OTHERS THEN

...嵌套了将近 30 个开始异常。

【问题讨论】:

为什么会有30个嵌套异常?你真的需要when others吗?或者你真的只是想捕捉no_data_found 异常?您能否将查询组合成一个带有一系列or 谓词的查询?还是会导致返回的行数过多? 您好,感谢您的回答,我需要的是根据其他列的值的组合在寄存器中返回列的值。函数中的参数可以为 NULL 或不为 NULL,例如表是 TARIFAS(id_client,port,container,tax) 并且有一个带有值 (100001,'CTG',NULL,'3.5') 的寄存器和另一个带有 ( 100001,'CTG','SM09','4.2')。所以我需要税收的价值。如果我使用 OR 谓词,在调用 FUNCTION TAX(100001,'CTG','SM09') 时会出现 too_many_values 错误。再次感谢您的帮助。 我假设“注册”是指“行”。如果您要提供示例数据,编辑问题非常有帮助,这样人们就不必滚动浏览 cmets。还要告诉我们预期的输出是什么以及为什么。在您的示例中,我不明白为什么您不能使用谓词 where tbl.container = p_container or (tbl.container IS NULL AND p_container IS NULL) 来选择一行,假设目标是获取 containerSM09 的行。 【参考方案1】:

恕我直言,这种类型的代码很难调试和维护。

如果我是正确的,代码是:

多次执行相同的查询,但 where 条件略有不同 使用异常捕获 NO_DATA_FOUND 异常(这是执行 select 语句时最可能出现的异常)

我建议:

尝试将多个查询聚合为一个,条件如下:

AND(TC.BL = PNUMBL 或 TC.BL 为空)

如果这是不可能的,做类似的事情

选择计数(*) 进入query1count 从 ... 其中...条件...

如果 (query1count>0) 那么 ...

其他

-- 做另一个查询

希望这会有所帮助。

【讨论】:

您好,感谢您的回答,我需要的是根据其他列的值的组合在寄存器中返回列的值。函数中的参数可以为 NULL 或不为 NULL,例如表是 TARIFAS(id_client,port,container,tax) 并且有一个带有值 (100001,'CTG',NULL,'3.5') 的寄存器和另一个带有 ( 100001,'CTG','SM09','4.2')。所以我需要税收的价值。如果我使用 OR 谓词,在调用 FUNCTION TAX(100001,'CTG','SM09') 时会出现 too_many_values 错误。再次感谢您的帮助。

以上是关于PL SQL 替代嵌套异常的主要内容,如果未能解决你的问题,请参考以下文章

PL/SQL 的数值优化或替代方案

PL/SQL 组函数的替代方案

PL/SQL Oracle 10g 询问用户输入(替代变量除外)

对于使用 Oracle pl sql 的 http 请求,是不是有替代 utl_http 包的方法?

Spark SQL 嵌套 JSON 错误“输入时没有可行的替代方案”

嵌套 CASE 的 T-SQL 替代方案以获得更好的性能?