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

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

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

  1. create or replace PROCEDURE SP_CONSULTA_PRECIO_MONEDA (idCliente IN INTEGER, items_tab IN ITEM_TAB, itemsPrice IN OUT RESULT_TAB)
  2. AS
  3. idTipoCliente INTEGER;
  4. precio NUMBER;
  5. idMoneda NUMBER;
  6. dFecha DATE;
  7. nFactor NUMBER;
  8. priceMxn NUMBER;
  9. priceUsd NUMBER;
  10. IdAlmacen INTEGER default 3;
  11. IdContrato INTEGER default 0;
  12. idCencosto INTEGER default 0;
  13. idPrecioDif INTEGER default 0;
  14. BEGIN
  15. -- Inicializando la tabla de resultados
  16. itemsPrice := RESULT_TAB();
  17. -- Obtener idTipoCliente
  18. SELECT ID_TIPOCTEPREC INTO idTipoCliente
  19. FROM CLIENTE
  20. WHERE ID_CLIENTE = idCliente;
  21. SELECT DFECHA, NFACTOR
  22. INTO dFecha, nFactor
  23. FROM tipocambio
  24. WHERE ROWNUM<2 ORDER BY id_tipocambio DESC;
  25. FOR i IN 1..items_tab.COUNT LOOP
  26. IF f_MTP_ConsultaPrecio(items_tab(i).itemId, idCliente, idTipoCliente, IdAlmacen, IdContrato, precio, idMoneda, idCencosto, idPrecioDif) THEN
  27. -- Calculando los precios
  28. IF idMoneda = 1 THEN
  29. priceMxn := precio;
  30. priceUsd := precio / nFactor;
  31. ELSE
  32. priceMxn := precio * nFactor;
  33. priceUsd := precio;
  34. END IF;
  35. priceMxn := CASE WHEN idMoneda = 1 THEN precio ELSE precio * nFactor END;
  36. priceUsd := CASE WHEN idMoneda = 2 THEN precio ELSE precio / nFactor END;
  37. -- Añadiendo el resultado a la tabla de resultados
  38. itemsPrice.EXTEND;
  39. itemsPrice(i) := RESULT_OBJ(
  40. items_tab(i).itemId,
  41. precio,
  42. idMoneda,
  43. dFecha,
  44. nFactor,
  45. priceMxn,
  46. priceUsd
  47. );
  48. ELSE
  49. itemsPrice.EXTEND;
  50. itemsPrice(i) := RESULT_OBJ(
  51. items_tab(i).itemId,
  52. NULL, -- precio
  53. NULL, -- id_moneda
  54. NULL, -- dFecha
  55. NULL, -- nFactor
  56. NULL, -- priceMxn
  57. NULL -- priceUsd
  58. );
  59. END IF;
  60. END LOOP;
  61. EXCEPTION
  62. WHEN NO_DATA_FOUND THEN
  63. idTipoCliente := 0;
  64. WHEN OTHERS THEN
  65. DBMS_OUTPUT.PUT_LINE(SQLERRM);
  66. END SP_CONSULTA_PRECIO_MONEDA;

这是我的JavaScript函数:

  1. async function getOrangeItemPrice(data) {
  2. let connection;
  3. try {
  4. connection = await oracledb.getConnection(dbConfig.oracle);
  5. const plsql = `BEGIN
  6. SP_CONSULTA_PRECIO_MONEDA (:idCliente, :items_tab, :itemsPrice);
  7. END;`;
  8. const binds = {
  9. idCliente: {
  10. type: oracledb.NUMBER,
  11. val: data.idCliente,
  12. },
  13. items_tab: {
  14. type: "ITEM_TAB",
  15. val: data.items,
  16. },
  17. itemsPrice: {
  18. dir: oracledb.BIND_OUT,
  19. type: oracledb.OBJECT,
  20. typeName: "RESULT_TAB",
  21. },
  22. };
  23. const options = { autoCommit: true, outFormat: oracledb.OUT_FORMAT_OBJECT };
  24. const spRS = await connection.execute(plsql, binds, options);
  25. const spResult = spRS.outBinds.itemsPrice;
  26. let rowData = [];
  27. while ((row = await spResult.getRow())) {
  28. let resp = {
  29. TYPE: row.OUTTYPE,
  30. MESSAGE: row.MESSAGE,
  31. COMPANYCTO: row.ROWS_COMPANYCTO,
  32. };
  33. rowData.push(resp);
  34. }
  35. await connection.close();
  36. return rowData;
  37. } catch (error) {
  38. throw boom.badRequest("Catch: " + error);
  39. }
  40. }

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

k5hmc34c

k5hmc34c1#

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

  1. itemsPrice IN OUT RESULT_TAB

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

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

相关问题