Oracle
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Oracle

lỗi node-oracledb khi thực hiện thủ tục được lưu trữ NJS-012

Cập nhật 2019/08/28:

Node-oracledb đã thêm hỗ trợ cho các loại đối tượng SQL và các loại bản ghi PL / SQL trong v4 (phát hành 2019/07/25). Xem phần này của tài liệu để biết chi tiết: https://oracle. github.io/node-oracledb/doc/api.html#objects

Với các đối tượng giống hệt như đã liệt kê trước đây, JavaScript sau có thể được sử dụng để thực hiện công việc với ít dòng mã hơn nhiều so với trước đây:

const oracledb = require('oracledb');
const config = require('./db-config.js');

async function runTest() {
  let conn;

  try {  
    const sql = 
     `call xxeta_grid_user_context_pkg.extract_grid_details(
        p_user_name      => :P_USER_NAME,
        p_content_type   => :P_CONTENT_TYPE,
        p_project_number => :P_PROJECT_NUMBER,
        op_grid_tab_typ  => :OP_GRID_TAB_TYP
      )`;

    const binds = {
      P_USER_NAME: 'Jane Doe',
      P_CONTENT_TYPE: 'Some Content Type',
      P_PROJECT_NUMBER: '123',
      OP_GRID_TAB_TYP: {
        dir: oracledb.BIND_OUT,
        type: 'HR.XXETA_GRID_CONTEXT_TAB_TYP'
      } 
    }

    conn = await oracledb.getConnection(config);

    const result = await conn.execute(
      sql,
      binds
    );

    const gridContexts = [];

    for (let x = 0; x < result.outBinds.OP_GRID_TAB_TYP.length; x += 1) {
      gridContexts.push({
        gridViewId: result.outBinds.OP_GRID_TAB_TYP[x].GRID_VIEW_ID,
        gridViewName: result.outBinds.OP_GRID_TAB_TYP[x].GRID_VIEW_NAME,
        userName: result.outBinds.OP_GRID_TAB_TYP[x].USER_NAME,
        projectNumber: result.outBinds.OP_GRID_TAB_TYP[x].PROJECT_NUMBER
      });
    }

    console.log(gridContexts);
  } catch (err) {
    console.error(err);
  } finally {
    if (conn) {
      try {
        await conn.close();
      } catch (err) {
        console.error(err);
      }
    }
  }
}

runTest();

Câu trả lời trước:

Các loại phức tạp hiện không được hỗ trợ. Ràng buộc ngoài mà bạn đã chỉ định nằm trong danh mục này. Cho đến khi các loại như vậy được hỗ trợ trực tiếp, bạn sẽ cần thêm một chút mã trình bao bọc để chia loại phức tạp thành một hoặc nhiều loại đơn giản. Tôi hiển thị một ví dụ về điều này ở đây: https://jsao.io/2017/01/plsql-record-types-and-the-node-js-driver/

Mục tiêu trong bài đăng đó là gọi một thủ tục được lưu trữ chấp nhận một mảng của loại bản ghi tùy chỉnh. Để gọi nó, trước tiên tôi phải khai báo một số kiểu mảng đơn giản để liên kết vào. Sau đó, tôi có thể sử dụng các mảng đó để tạo mảng phức tạp hơn và gọi thủ tục.

Trong trường hợp của bạn, bạn sẽ cần làm ngược lại. Trong khối PL / SQL, khai báo một biến cục bộ thuộc loại APPS.XXETA_GRID_CONTEXT_TAB_TYP. Sau đó, sau khi thủ tục được gọi, hãy lặp lại mảng và sử dụng nó để điền vào một số mảng đơn giản (VARCHAR2, NUMBER hoặc DATE) và sử dụng chúng làm liên kết ngoài của bạn.

Cập nhật:

Miễn là bạn có các đối tượng sau:

create or replace type xxeta_grid_context_rec_typ as object (
  grid_view_id   number(15),
  grid_view_name varchar2(240),
  user_name      varchar2(30),
  project_number varchar2(5)
)
/

create or replace type xxeta_grid_context_tab_typ as table of xxeta_grid_context_rec_typ
/

create or replace package xxeta_grid_user_context_pkg
as

procedure extract_grid_details(
  p_user_name      in varchar2,
  p_content_type   in varchar2,
  p_project_number in varchar2,
  op_grid_tab_typ  out xxeta_grid_context_tab_typ
);

end;
/

create or replace package body xxeta_grid_user_context_pkg
as

procedure extract_grid_details(
  p_user_name      in varchar2,
  p_content_type   in varchar2,
  p_project_number in varchar2,
  op_grid_tab_typ  out xxeta_grid_context_tab_typ
)

is

  l_xxeta_grid_context_rec xxeta_grid_context_rec_typ;

begin

  op_grid_tab_typ := xxeta_grid_context_tab_typ();

  for x in 1 .. 3
  loop
    l_xxeta_grid_context_rec := xxeta_grid_context_rec_typ(
      grid_view_id   => x,
      grid_view_name => 'Some Grid View',
      user_name      => p_user_name,
      project_number => p_project_number
    );

    op_grid_tab_typ.extend();

    op_grid_tab_typ(x) := l_xxeta_grid_context_rec;
  end loop;

end;

end;
/

Mã Node.js sau đây có thể gọi thủ tục được lưu trữ và nhận các giá trị từ tham số phức tạp.

const oracledb = require('oracledb');
const config = require('./dbConfig.js');

async function runTest() {
  let conn;

  try {
    const userName = 'Jane Doe';
    const contentType = 'Some Content Type';
    const projectNumber = '123';

    // This is what we want to populate with records/objects that come out
    // of the procedure.
    const gridContexts = [];

    // We start by declaring some other arrays, one for each field in the
    // xxeta_grid_context_rec_typ type.
    const gridViewIds = [];
    const gridViewNames = [];
    const userNames = [];
    const projectNumbers = []; 

    conn = await oracledb.getConnection(config);

    // Then we execute the procedure with a little wrapper code to populate
    // the individual arrays.
    let result = await conn.execute(
     `declare

        -- This is a local variable that you'll use to get the out data from
        -- the procedure.
        l_xxeta_grid_context_tab xxeta_grid_context_tab_typ;

      begin

        xxeta_grid_user_context_pkg.extract_grid_details(
          p_user_name      => :user_name,
          p_content_type   => :content_type,
          p_project_number => :project_number,
          op_grid_tab_typ  => l_xxeta_grid_context_tab
        );

        -- Now that the local variable is populated, iterate over it to
        -- populate the individual out binds.
        for x in 1 .. l_xxeta_grid_context_tab.count
        loop
          :grid_view_ids(x) := l_xxeta_grid_context_tab(x).grid_view_id;
          :grid_view_names(x) := l_xxeta_grid_context_tab(x).grid_view_name;
          :user_names(x) := l_xxeta_grid_context_tab(x).user_name;
          :project_numbers(x) := l_xxeta_grid_context_tab(x).project_number;
        end loop;

      end;`,
      {
        user_name: userName,
        content_type: contentType,
        project_number: projectNumber,
        grid_view_ids: {
          dir: oracledb.BIND_OUT,
          type: oracledb.NUMBER,
          maxArraySize: 200
        },
        grid_view_names: {
          dir: oracledb.BIND_OUT,
          type: oracledb.STRING,
          maxArraySize: 200
        },
        user_names: {
          dir: oracledb.BIND_OUT,
          type: oracledb.STRING,
          maxArraySize: 200
        },
        project_numbers: {
          dir: oracledb.BIND_OUT,
          type: oracledb.STRING,
          maxArraySize: 200
        }
      }
    );

    // At this point you can access the individual arrays to populate the 
    // original target array with objects. This is optional, you can work
    // with the individual arrays directly as well.
    for (let x = 0; x < result.outBinds.grid_view_ids.length; x += 1) {
      gridContexts.push({
        gridViewId: result.outBinds.grid_view_ids[x],
        gridViewName: result.outBinds.grid_view_names[x],
        userName: result.outBinds.user_names[x],
        projectNumber: result.outBinds.project_numbers[x]
      });
    }

    console.log(gridContexts);
  } catch (err) {
    console.error(err);
  } finally {
    if (conn) {
      try {
        await conn.close();
      } catch (err) {
        console.error(err);
      }
    }
  }
}

runTest();

Tôi hy vọng rằng sẽ giúp! Hỗ trợ trực tiếp cho các loại phức tạp nằm trong danh sách các cải tiến, chỉ không thể nói khi nào nó sẽ hạ cánh.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Python cx_Oracle SQL với biến chuỗi liên kết

  2. Quyền truy cập mạng Oracle 12c Apex 4.2 ORA-24247 bị từ chối bởi danh sách kiểm soát truy cập (ACL)

  3. Oracle và Left Outer Tham gia

  4. Cập nhật oracle bảng phân vùng

  5. Xử lý null khi sử dụng Oracle XMLType