Oracle
 sql >> Baza danych >  >> RDS >> Oracle

Wywołanie procedury Oracle z typem rekordu PL/SQL z Spring JDBC

Niestety sterownik Oracle JDBC nie zapewnia dostępu do PL/SQL RECORD wpisz, ani dla IN ani dla OUT parametry.

Obejście dla pojedynczego wywołania procedury:

Ale możesz obejść to ograniczenie, używając anonimowego bloku PL/SQL bezpośrednio w JDBC (lub 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;

Działa to doskonale dla pojedynczego wywołania procedury.

Solidne rozwiązanie dla wielu z tych połączeń:

Jeśli robisz powyższe dość często, warto generować kody pośredniczące, które automatycznie generują anonimowe ciągi PL/SQL, zamiast pisać je ręcznie przez cały czas. Możesz automatycznie wykryć wszystkie PL/SQL RECORD typów w schemacie za pomocą następującego zapytania:

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

Zobacz więcej szczegóły dotyczące tej techniki w tym poście na blogu (z którego pochodzi zapytanie) .



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. oracle Wybierz daty dla przedmiotów sprzedanych w odstępie 1 minuty od siebie

  2. Jak tworzyć kolumny przyrostowe?

  3. Jak wyodrębnić numer miesiąca od daty w Oracle

  4. Jak sprawdzić, czy klient Oracle jest zainstalowany lub nie jako warunek wstępny instalacji komponentu?

  5. Usuń liczby znalezione w kolumnie ciągu