sql >> データベース >  >> RDS >> Oracle

SpringJDBCからPL/SQLレコードタイプを使用してOracleプロシージャを呼び出す

    残念ながら、OracleJDBCドライバはPL/ SQL RECORDへのアクセスを提供しません。 タイプ、INのどちらでもない OUTも パラメータ。

    単一のプロシージャ呼び出しの回避策:

    ただし、JDBC(またはSpring JDBC)で匿名のPL / SQLブロックを直接使用することで、この制限を回避できます。

    DECLARE
      rec MY_PACKAGE.MY_RECORD;
    BEGIN
    
      -- Replace these by your actual record attributes:
      rec.first_name := ?;
      rec.last_name := ?;
      ...
    
      p_insertclient(rec);
    END;
    

    これは、1回のプロシージャ呼び出しで完全に機能します。

    これらの呼び出しの多くに対する固溶体:

    上記を頻繁に行う場合は、匿名のPL / SQL文字列を常に手動で書き込むのではなく、自動的に生成するスタブを生成する価値があります。すべてのPL/SQL RECORDを自動的に検出できます 次のクエリでスキーマを入力します:

    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
    

    詳細このブログ投稿(クエリの取得元)にあるこの手法の詳細



    1. SQLServerで文字列の左または右から特定の数の文字を選択する方法

    2. MySQLの共通テーブル式

    3. 条件で切り捨てる

    4. 教義 2:SQL Server 2008apm で DateTime 列を更新できない