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

Gọi thủ tục Oracle với Loại bản ghi PL / SQL từ Spring JDBC

Rất tiếc, trình điều khiển Oracle JDBC không cung cấp quyền truy cập vào PL / SQL RECORD nhập, không cho IN cũng không cho OUT tham số.

Giải pháp cho một lệnh gọi thủ tục:

Nhưng bạn có thể khắc phục hạn chế này bằng cách sử dụng trực tiếp khối PL / SQL ẩn danh trong JDBC (hoặc Spring JDBC):

DECLARE
  rec MY_PACKAGE.MY_RECORD;
BEGIN

  -- Replace these by your actual record attributes:
  rec.first_name := ?;
  rec.last_name := ?;
  ...

  p_insertclient(rec);
END;

Điều này hoạt động hoàn toàn tốt cho một lệnh gọi thủ tục.

Giải pháp ổn định cho nhiều cuộc gọi sau:

Nếu bạn thực hiện những điều trên khá thường xuyên, bạn nên tạo các sơ khai tạo ra các chuỗi PL / SQL ẩn danh tự động, thay vì luôn luôn viết các chuỗi đó theo cách thủ công. Bạn có thể tự động khám phá tất cả RECORD PL / SQL nhập vào lược đồ của bạn với truy vấn sau:

SELECT
  x.TYPE_OWNER, x.TYPE_NAME, x.TYPE_SUBNAME, a.ARGUMENT_NAME ATTR_NAME,
  a.SEQUENCE ATTR_NO, a.TYPE_OWNER ATTR_TYPE_OWNER,
  nvl2(a.TYPE_SUBNAME, a.TYPE_NAME, NULL) package_name,
  COALESCE(a.TYPE_SUBNAME, a.TYPE_NAME, a.DATA_TYPE) ATTR_TYPE_NAME,
  a.DATA_LENGTH LENGTH, a.DATA_PRECISION PRECISION, a.DATA_SCALE SCALE
FROM SYS.ALL_ARGUMENTS a
JOIN (
  SELECT
    a.TYPE_OWNER, a.TYPE_NAME, a.TYPE_SUBNAME,
    MIN(a.OWNER) KEEP (DENSE_RANK FIRST ORDER BY a.OWNER ASC, a.PACKAGE_NAME ASC, a.SUBPROGRAM_ID ASC, a.SEQUENCE ASC) OWNER,
    MIN(a.PACKAGE_NAME) KEEP (DENSE_RANK FIRST ORDER BY a.OWNER ASC, a.PACKAGE_NAME ASC, a.SUBPROGRAM_ID ASC, a.SEQUENCE ASC) PACKAGE_NAME,
    MIN(a.SUBPROGRAM_ID) KEEP (DENSE_RANK FIRST ORDER BY a.OWNER ASC, a.PACKAGE_NAME ASC, a.SUBPROGRAM_ID ASC, a.SEQUENCE ASC) SUBPROGRAM_ID,
    MIN(a.SEQUENCE) KEEP (DENSE_RANK FIRST ORDER BY a.OWNER ASC, a.PACKAGE_NAME ASC, a.SUBPROGRAM_ID ASC, a.SEQUENCE ASC) SEQUENCE,
    MIN(next_sibling) KEEP (DENSE_RANK FIRST ORDER BY a.OWNER ASC, a.PACKAGE_NAME ASC, a.SUBPROGRAM_ID ASC, a.SEQUENCE ASC) next_sibling,
    MIN(a.DATA_LEVEL) KEEP (DENSE_RANK FIRST ORDER BY a.OWNER ASC, a.PACKAGE_NAME ASC, a.SUBPROGRAM_ID ASC, a.SEQUENCE ASC) DATA_LEVEL
  FROM (
    SELECT
      lead(a.SEQUENCE, 1, a.SEQUENCE) OVER (
        PARTITION BY a.OWNER, a.PACKAGE_NAME, a.SUBPROGRAM_ID, a.DATA_LEVEL
        ORDER BY a.SEQUENCE ASC
      ) next_sibling,
      a.TYPE_OWNER, a.TYPE_NAME, a.TYPE_SUBNAME, a.OWNER, a.PACKAGE_NAME, 
      a.SUBPROGRAM_ID, a.SEQUENCE, a.DATA_LEVEL, a.DATA_TYPE
    FROM SYS.ALL_ARGUMENTS a
    WHERE a.OWNER IN ('MY_SCHEMA')     -- Possibly replace schema here
    ) a
  WHERE (a.TYPE_OWNER IN ('MY_SCHEMA') -- Possibly replace schema here
  AND a.OWNER         IN ('MY_SCHEMA') -- Possibly replace schema here
  AND a.DATA_TYPE      = 'PL/SQL RECORD')
  GROUP BY a.TYPE_OWNER, a.TYPE_NAME, a.TYPE_SUBNAME
  ) x
ON ((a.OWNER, a.PACKAGE_NAME, a.SUBPROGRAM_ID) = ((x.OWNER, x.PACKAGE_NAME, x.SUBPROGRAM_ID))
AND a.SEQUENCE BETWEEN x.SEQUENCE AND next_sibling
AND a.DATA_LEVEL = (x.DATA_LEVEL + 1))
ORDER BY x.TYPE_OWNER ASC, x.TYPE_NAME ASC, x.TYPE_SUBNAME ASC, a.SEQUENCE ASC

Xem thêm chi tiết về kỹ thuật này trong bài đăng blog này (từ đó truy vấn được thực hiện) .



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. sự khác biệt giữa bảng tab và all_tables trong oracle

  2. PL / SQL FTP API nhị phân so với chế độ ascii

  3. Oracle / SQL:Tại sao truy vấn SELECT * FROM các bản ghi WHERE rownum> =5 VÀ rownum <=10 - trả về 0 hàng

  4. Oracle JDBC ký tự Euro

  5. Chèn một chuỗi có dấu ngoặc kép vào bảng