使用TYPE TABLE BIND OUT从Oracle存储过程获取结果集

wz1wpwve  于 2023-10-16  发布在  Oracle
关注(0)|答案(1)|浏览(138)

我试图在Express JS中执行一个带有“oracledb”依赖项的SP,但当我试图从RS获取数据时,会抛出此错误:
错误:NJS-012:在参数% 2中遇到无效的绑定数据类型
这是我的SP。使用Oracle 11 G:

create or replace PROCEDURE SP_CONSULTA_PRECIO_MONEDA (idCliente IN INTEGER, items_tab IN ITEM_TAB, itemsPrice IN OUT RESULT_TAB)
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;
BEGIN
   -- Inicializando la tabla de resultados
    itemsPrice := RESULT_TAB();

    -- 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
            IF idMoneda = 1 THEN 
                priceMxn := precio;
                priceUsd := precio / nFactor;
            ELSE 
                priceMxn := precio * nFactor;
                priceUsd := precio;
            END IF;
            
            priceMxn := CASE WHEN idMoneda = 1 THEN precio ELSE precio * nFactor END;
            priceUsd := CASE WHEN idMoneda = 2 THEN precio ELSE precio / nFactor END;

            -- 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
            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;
EXCEPTION
    WHEN NO_DATA_FOUND THEN
        idTipoCliente := 0;
    WHEN OTHERS THEN
        DBMS_OUTPUT.PUT_LINE(SQLERRM);
END SP_CONSULTA_PRECIO_MONEDA;

这是我的JavaScript函数:

async function getOrangeItemPrice(data) {
  let connection;

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

    const plsql = `BEGIN
                      SP_CONSULTA_PRECIO_MONEDA (:idCliente, :items_tab, :itemsPrice);
                   END;`;

    const binds = {
      idCliente: {
        type: oracledb.NUMBER,
        val: data.idCliente,
      },
      items_tab: {
        type: "ITEM_TAB",
        val: data.items,
      },
      itemsPrice: {
        dir: oracledb.BIND_OUT,
        type: oracledb.OBJECT,
        typeName: "RESULT_TAB",
      },
    };

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

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

    const spResult = spRS.outBinds.itemsPrice;

    let rowData = [];
    while ((row = await spResult.getRow())) {
      let resp = {
        TYPE: row.OUTTYPE,
        MESSAGE: row.MESSAGE,
        COMPANYCTO: row.ROWS_COMPANYCTO,
      };

      rowData.push(resp);
    }

    await connection.close();

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

我做了另一个SP来测试items_tab是否是问题所在,并将itemsPrice更改为RETURSOR,在光标上返回一个虚拟响应,可以工作,但使用RESULT_TAB不能工作。
我想捕捉itemsPrice上返回的信息。我需要在代码中更改哪些内容?我在Oracle中测试了SP并正常工作。

k5hmc34c

k5hmc34c1#

您已将参数设置为oracledb.BIND_OUT,但该参数不是您定义的OUT参数:

itemsPrice IN OUT RESULT_TAB

使用oracledb.BIND_INOUT或将过程的签名更改为:

itemsPrice OUT RESULT_TAB
  • (不清楚为什么要使用IN OUT参数,因为在过程中要做的第一件事就是设置值,该值将覆盖您传入的任何值。

相关问题