从Oracle SP on Express获取数据

k4emjkb1  于 2023-11-17  发布在  Oracle
关注(0)|答案(1)|浏览(157)

我在Oracle中有一个SP,我从一个TYPE TABLE中返回数据,但是当数据到达代码中时,所有属性都是NULL。这是我的SP:

create or replace PROCEDURE SP2 (idCliente IN INTEGER, items_tab IN ITEM_TAB, pCursor OUT SYS_REFCURSOR)
AS
    idTipoCliente INTEGER;
    precio    NUMBER;
    idMoneda  NUMBER;
    dFecha  DATE;
    nFactor NUMBER;
    priceMxn NUMBER;
    priceUsd NUMBER;
    IdAlmacen INTEGER default 3;
    IdContrato INTEGER default 0;
    idCencosto INTEGER default 0;
    idPrecioDif INTEGER default 0;
    itemsPrice RESULT_TAB := RESULT_TAB();
BEGIN
   -- Inicializando la tabla de resultados

    -- Obtener idTipoCliente
    SELECT ID_TIPOCTEPREC INTO idTipoCliente 
        FROM CLIENTE 
        WHERE ID_CLIENTE = idCliente;
    
    SELECT DFECHA, NFACTOR 
                INTO dFecha, nFactor
                FROM tipocambio 
                WHERE ROWNUM<2 ORDER BY id_tipocambio DESC;
                
    FOR i IN 1..items_tab.COUNT LOOP
        IF f_MTP_ConsultaPrecio(items_tab(i).itemId, idCliente, idTipoCliente, IdAlmacen, IdContrato, precio, idMoneda, idCencosto, idPrecioDif) THEN
            -- Calculando los precios
            priceMxn := CASE WHEN idMoneda = 1 THEN precio ELSE precio * nFactor END;
            priceUsd := CASE WHEN idMoneda = 2 THEN precio ELSE precio / nFactor END;
            
            --DBMS_OUTPUT.PUT_LINE('Item ID: ' || items_tab(i).itemId || ', Precio: ' || TO_CHAR(precio) || ', ID Moneda: ' || TO_CHAR(idMoneda) || ', Fecha: ' || TO_CHAR(dFecha) || ', Factor: ' || TO_CHAR(nFactor) || ', Precio MXN: ' || TO_CHAR(priceMxn) || ', Precio USD: ' || TO_CHAR(priceUsd));
            -- Añadiendo el resultado a la tabla de resultados
            itemsPrice.EXTEND;
            itemsPrice(i) := RESULT_OBJ(
                items_tab(i).itemId,
                precio,
                idMoneda,
                dFecha,
                nFactor,
                priceMxn,
                priceUsd
            );
            
        ELSE
        DBMS_OUTPUT.PUT_LINE('wdadw');
            itemsPrice.EXTEND;
            itemsPrice(i) := RESULT_OBJ(
                items_tab(i).itemId,
                NULL, -- precio
                NULL, -- id_moneda
                NULL, -- dFecha
                NULL, -- nFactor
                NULL, -- priceMxn
                NULL  -- priceUsd
            );
        END IF;
    END LOOP;
    
    OPEN pCursor FOR
        SELECT * FROM TABLE(itemsPrice);
    
EXCEPTION
    WHEN NO_DATA_FOUND THEN
        idTipoCliente := 0;
    WHEN OTHERS THEN
        DBMS_OUTPUT.PUT_LINE(SQLERRM);
END SP2;

字符串
这是我的类型

create or replace TYPE ITEMS_OBJ AS OBJECT (
   itemId NUMBER
);

create or replace TYPE ITEM_TAB AS TABLE OF ITEMS_OBJ;

create or replace TYPE RESULT_OBJ AS OBJECT (
   ITEMID   NUMBER(9, 0),
   PRECIO    NUMBER(13,4),
   ID_MONEDA NUMBER(9, 0),
   DFECHA    DATE,
   NFACTOR   NUMBER(13,4),
   PRICEMXN  NUMBER(13,4),
   PRICEUSD  NUMBER(13,4)
);

create or replace TYPE RESULT_TAB AS TABLE OF RESULT_OBJ;


当我在Oracle上执行SP时,输出如下:

Item ID: 123494, Precio: 289.59, Moneda: 1, Fecha: 26-SEP-2023, Factor: 17.3733, Precio MXN: 289.59, Precio USD: 16.6687
Item ID: 5991, Precio: 205.3711, Moneda: 2, Fecha: 26-SEP-2023, Factor: 17.3733, Precio MXN: 3567.9744, Precio USD: 205.3711
Item ID: 129782, Precio: 60.613, Moneda: 2, Fecha: 26-SEP-2023, Factor: 17.3733, Precio MXN: 1053.0471, Precio USD: 60.613
Item ID: 96157, Precio: 45.143, Moneda: 1, Fecha: 26-SEP-2023, Factor: 17.3733, Precio MXN: 45.143, Precio USD: 2.5984
Item ID: 114161, Precio: 26.045, Moneda: 1, Fecha: 26-SEP-2023, Factor: 17.3733, Precio MXN: 26.045, Precio USD: 1.4991


但是当我在节点上执行这个SP时,我得到的所有数据都是NULL,如下所示:

{ITEMID: null, PRECIO: null, ID_MONEDA: null, DFECHA: null, NFACTOR: null, …}


这是我的功能:

async function getOrangeItemPrice(data) {
  let connection;

  try {
    connection = await oracledb.getConnection(dbConfig.oracle);

    const plsql = `BEGIN
                      SP2 (:idCliente, :items_tab, :pCursor);
                   END;`;

    const binds = {
      idCliente: {
        type: oracledb.NUMBER,
        val: data.clientId,
      },
      items_tab: {
        type: "ITEM_TAB",
        val: data.items,
      },
      pCursor: {
        dir: oracledb.BIND_OUT,
        type: oracledb.CURSOR,
      },
    };

    const options = { autoCommit: true, outFormat: oracledb.OUT_FORMAT_OBJECT };

    const spRS = await connection.execute(plsql, binds, options);

    const spResult = spRS.outBinds.pCursor;

    let rowData = [];
    while ((row = await spResult.getRow())) {
      let resp = {
        DFECHA: row.DFECHA,
        ID_MONEDA: row.ID_MONEDA,
        ITEMID: row.ITEMID,
      };

      rowData.push(resp);
    }

    await connection.close();

    return rowData;
  } catch (error) {
    throw boom.badRequest("Catch: " + error);
  }
}


我必须在SP上更改什么才能获取所有数据?
我测试改变这部分检查数据fech和作品:

OPEN pCursor FOR
        SELECT 'TEST' as outType FROM DUAL;


但是对于TYPE TABLE SELECT,

eh57zj3b

eh57zj3b1#

可能的解决方案和调试方法的一些建议:
1.可以将ITEM_TAB简化为:

CREATE TYPE ITEM_TAB AS TABLE OF NUMBER;

字符串
然后删除ITEMS_OBJ对象,因为它是不必要的。在这个过程中,你将使用items_tab(i)而不是items_tab(i).itemId
在Node中使用一个简单的数字表可能比传递一个对象表要容易得多。
1.在Oracle中,如果将过程调用为:

DECLARE
  v_cur SYS_REFCURSOR;
BEGIN
  SP2 (1, ITEM_TAB(ITEMS_OBJ(1), ITEMS_OBJ(2),ITEMS_OBJ(3)), v_cur);
END;
/


或者如果你已经删除了ITEMS_OBJ并使用了一个数字表:

DECLARE
  v_cur SYS_REFCURSOR;
BEGIN
  SP2 (1, ITEM_TAB(1, 2, 3), v_cur);
END;
/


然后在Node中,尝试使用PL/SQL块中定义的静态值调用过程,看看是否有效:

const plsql = `BEGIN
                 SP2 (:idCliente, ITEM_TAB(1, 2, 3), :pCursor);
               END;`;

const binds = {
  idCliente: {
    type: oracledb.NUMBER,
    val: data.clientId,
  },
  pCursor: {
    dir: oracledb.BIND_OUT,
    type: oracledb.CURSOR,
  },
};


如果它确实有效,那么你就知道问题出在集合的绑定上,并且可以看看如何解决这个问题。
如果它不起作用,那么你可以简化更多,直到你可以锻炼的问题。
1.你调用f_MTP_ConsultaPrecio,如果函数返回FALSE,那么你输出NULL值。你确定你的过程没有正确执行,而是这个函数失败了吗?

相关问题