微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何使用一个功能测试我的包裹?

如何解决如何使用一个功能测试我的包裹?

我制作了一个可以正常编译的软件包,但是当我尝试对其进行测试时,它给出了“无效的数据类型”。 我尝试了两种不同的方法,第一种是这样的

select pkg_contabilidad.f_totalizar_Detalle(100) FROM DUAL;

这给了我ORA-00902'无效的数据类型' 我也试过了

DECLARE 
    TYPE r_registro IS RECORD
    (rubro_contable CN_RUbroS_CONTABLES.COD_RUbro%TYPE,tipo VARCHAR2(1),monto NUMBER(16));
    resultao r_registro;
    numero NUMBER :=100;
BEGIN
    resultao := pkg_contabilidad.f_totalizar_detalle(numero);
END;

它给了我另一个错误PLS-00382'表达式类型错误' 我不知道我在做什么错,因为我的函数仅接收到一个参数并且类型为NUMBER,所以我不知道我的错误在哪里。我会保留包裹中的代码以防万一

CREATE OR REPLACE PACKAGE pkg_contabilidad AS
TYPE r_registro IS RECORD
(rubro_contable CN_RUbroS_CONTABLES.COD_RUbro%TYPE,monto NUMBER(16));
TYPE t_detalle IS TABLE OF
r_registro INDEX BY BINARY_INTEGER;
FUNCTION f_totalizar_detalle(p_clave NUMBER)RETURN t_detalle;
END pkg_contabilidad;
/
CREATE OR REPLACE PACKAGE BODY pkg_contabilidad AS
B_detalle t_detalle;
i integer :=1;
FUNCTION f_totalizar_detalle(p_clave NUMBER) RETURN t_detalle IS
    v_detalle t_detalle;
    CURSOR c_facturado IS 
    SELECT c.cod_rubro,'H',CASE WHEN SUM(d.gravada)=0 THEN SUM(d.iva) ELSE SUM(d.gravada) END
    FROM fn_documentos_det d JOIN fn_conceptos c ON d.cod_concepto = c.cod_concepto
    WHERE d.clave_doc=p_clave
    GROUP BY c.cod_rubro;
    
    CURSOR c_datos IS
    SELECT SUM(d.total_doc),'D',r.cod_rubro 
    FROM fn_documentos d JOIN fn_cajas_ctas r ON d.num_caja_cta = r.num_caja_cta
    WHERE d.clave_doc = p_clave
    GROUP BY r.cod_rubro;
BEGIN
    open c_datos;
    LOOP
    FETCH c_datos INTO v_detalle(1);
    END LOOP;
    CLOSE c_datos;
    FOR fila IN c_facturado LOOP
    i := i + 1;
    v_detalle(i) := fila;
    END LOOP;
END;
END PKG_CONTABILIDAD;

解决方法

该函数返回一个pkg_contabilidad.t_detalle,因此测试必须为:

declare
    resultao pkg_contabilidad.t_detalle;
    numero   number := 100;
begin
    resultao := pkg_contabilidad.f_totalizar_detalle(numero);
end;

它在SQL中不起作用,因为pkg_contabilidad.t_detalle是PL / SQL类型,而不是SQL类型(create or replace type)。数据库可以执行一些自动转换,但是仍然存在限制。

顺便说一句,此循环将永远不会完成,因为它缺少exit条件:

open c_datos;
loop
    fetch c_datos into v_detalle(1);
end loop;
close c_datos;
,

您的函数返回一个PL / SQL表类型,该表具有一个PL / SQL记录类型的表,该表在您的包中定义,普通的SQL不知道也不可以显示-因此,您无效的数据类型错误。如果您需要调用该函数并通过SQL访问数据,则可以创建模式级别的对象和集合类型。

在您的匿名区块中,您声明的是 new 记录类型。在您看来,这是相同的,因为结构相同,但是Oracle希望函数返回的确切类型。但是,这会使您的测试代码更短,更简单。但是,您也试图将整个集合返回到一条记录中。

DECLARE 
    l_detalle pkg_contabilidad.t_detalle;
    l_registro pkg_contabilidad.r_registro;
    l_idx pls_integer;
    numero NUMBER :=100;
BEGIN
    l_detalle := pkg_contabilidad.f_totalizar_detalle(numero);
    l_idx := l_detalle.FIRST;
    WHILE l_idx is not null LOOP
        l_registro := l_detalle(l_idx);
        -- do something with this record
        dbms_output.put_line(l_registro.tipo);
        l_idx := l_detalle.NEXT(l_idx);
    END LOOP;
END;

db<>fiddle(带有虚拟光标)。

您的功能有些奇怪,可能没有完全按照您的要求进行;但还有两个致命的问题:它不返回任何东西,并且具有无限循环。我已经将它们固定为小提琴,但没有其他任何设置,因为这似乎是一种练习。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。