質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.51%
Oracle

Oracleは、米オラクルが取り扱うリレーショナルデータベース管理システムです。メインフレームからPCまで、多様なプラットフォームに対応しています。

PL/SQL

PL/SQL (Procedural Language/Structured Query Language) はOracle CorporationによるSQL(非手続き型言語)を手続き型言語に拡張させるために開発されたプログラミング言語です。

Q&A

解決済

1回答

1949閲覧

oracle triggerでOUT引数を持つfunctionの呼び出し方法

kakizaki

総合スコア9

Oracle

Oracleは、米オラクルが取り扱うリレーショナルデータベース管理システムです。メインフレームからPCまで、多様なプラットフォームに対応しています。

PL/SQL

PL/SQL (Procedural Language/Structured Query Language) はOracle CorporationによるSQL(非手続き型言語)を手続き型言語に拡張させるために開発されたプログラミング言語です。

0グッド

0クリップ

投稿2018/08/08 02:07

編集2018/08/10 01:39

前提・実現したいこと

お世話になっております。

Oracleのtriggerを使用して、同じスキーマ内のfunctionの呼び出しに難儀しております。
triggerから同じスキーマ内のOUT引数を持つfunctionの呼び出しで、実行時エラーが発生しております。

DB:oracle12c

発生している問題・エラーメッセージ

SQL Developer のエラーメッセージ EXCEPTION_ORA_6572 【エラー内容】 ORA-06572: ファンクションstringに出力引数が指定されています 原因: SQL文が、引数リストにOUTパラメータが含まれているパッケージ化されたPL/SQLファンクションまたはスタンドアロンPL/SQLファンクションのどちらかを参照しています。SQL文によって参照されるPL/SQLファンクションには、OUTパラメータが含まれていてはいけません。 処置: 引数リストでOUTパラメータを使用せずに、PL/SQLファンクションを再作成してください。

該当のソースコード

PL/SQL

1--トリガー作成 2CREATE OR REPLACE TRIGGER TEST_TRIGGER 3AFTER INSERT OR DELETE OR UPDATE 4ON TEST_TABLE_A 5REFERENCING OLD AS OLD NEW AS NEW 6FOR EACH ROW 7DECLARE 8 vRET_SQLERR_CD NUMBER; 9 vRET_SQLERR_MSG VARCHAR2(500); 10BEGIN 11 IF INSERTING THEN 12 INSERT INTO TEST_TABLE_B VALUES (FNC_GET_NEXTVAL('KANRI_ID',vRET_SQLERR_CD,vRET_SQLERR_MSG), :NEW.FIELD_A, :NEW.FIELD_B); 13 END IF; 14END; 15/ 16 17-- 更新元テーブル 18CREATE TABLE TEST_TABLE_A( 19 KANRI_NO NUMBER, 20 FIELD_A VARCHAR2(10), 21 FIELD_B VARCHAR2(10) 22); 23 24-- 更新先テーブル 25CREATE TABLE TEST_TABLE_B( 26 KANRI_NO NUMBER, 27 FIELD_A VARCHAR2(10), 28 FIELD_B VARCHAR2(10) 29); 30 31-- ファンクション作成 32CREATE OR REPLACE FUNCTION FNC_GET_NEXTVAL ( 33 ------------------------------------------------------------ 34 -- 次管理番号取得用 35 -- IN : KANRI_ID 管理番号ID 36 -- OUT : RET_SQLERR_CD SQLエラーコード 37 -- RET_SQLERR_MSG SQLエラーメッセージ 38 -- RETURN 39 -- 次管理番号 40 -- ※エラー発生の場合、-1を返す 41 ------------------------------------------------------------ 42 KANRI_ID IN VARCHAR2, 43 RET_SQLERR_CD OUT NUMBER, 44 RET_SQLERR_MSG OUT VARCHAR2 45) RETURN NUMBER IS 46 v_nextval NUMBER := -1; 47 v_SQL VARCHAR2(200); 48 v_KANRI_ID VARCHAR2(30); 49BEGIN 50 -- 次管理番号取得処理を実行 51 RETURN v_nextval; 52EXCEPTION 53 -- エラー発生 54 RET_SQLERR_CD := SQLCODE; 55 RET_SQLERR_MSG := SQLERRM; 56 57 RETURN -1; 58END; 59/ 60

試したこと

OUT引数に nullや0 を設定しましたが、結果は変わりませんでした。

補足情報(FW/ツールのバージョンなど)

ここにより詳細な情報を記載してください。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Orlofsky

2018/08/08 14:04

質問にCREATE TABLE文とPKG_UTLのCREATE PACKGE, CREATE PACKGE BODY も載せないと適切なコメントはできないかと。
Orlofsky

2018/08/09 20:29

PL/SQL タグを追加してください。
guest

回答1

0

ベストアンサー

EXCEPTIONも含めて常にRETURNが -1 で良いのか?とか、
INSERT文では PKG_UTL.FNC_GET_NEXTVAL になっているのに、
CREATE OR REPLACE FUNCTION FNC_GET_NEXTVAL とPACKAGEではなくFUNCTIONになっているのはエラーになるとか、突っ込みどころ満載です。

SQL

1-- ファンクション作成 2CREATE OR REPLACE FUNCTION FNC_GET_NEXTVAL ( 3 -- 次管理番号取得用 4 I_KANRI_ID IN VARCHAR2, -- 管理番号ID -- 使ってないけど 5 O_SQLERR_CD OUT NUMBER, -- SQLエラーコード 6 O_SQLERR_MSG OUT VARCHAR2 -- SQLエラーメッセージ 7 ) 8 RETURN NUMBER -- 次管理番号 ※エラー発生の場合、-1を返す (常にRETURNは -1) 9 IS 10 v_nextval NUMBER := -1; 11BEGIN 12 O_SQLERR_CD := 0; 13 O_SQLERR_MSG := NULL; 14 -- 次管理番号取得処理を実行 15 RETURN v_nextval; 16EXCEPTION 17 -- エラー発生 18 O_SQLERR_CD := SQLCODE; 19 -- ↓ エラーメッセージにはSQLERRM以外にもFUNCTION名やSELECTするであろうテーブルのKRIMARY KEY の内容も追加しないと運用で困るのでは? 20 O_SQLERR_MSG := SQLERRM; 21 22 RETURN -1; 23END; 24/

SQL

1--トリガー作成 2CREATE OR REPLACE TRIGGER TEST_TRIGGER 3AFTER INSERT OR DELETE OR UPDATE 4ON TEST_TABLE_A 5REFERENCING OLD AS OLD NEW AS NEW 6FOR EACH ROW 7DECLARE 8 v_KANRI_NO TEST_TABLE_B.KANRI_NO%TYPE ; 9 v_SQLERR_CD NUMBER; 10 v_SQLERR_MSG VARCHAR2(500); 11BEGIN 12 IF INSERTING THEN 13 -- TRIGGER は PL/SQLだからOUT引数が使えるが、TRIGGERの中のINSERTはSQLだからOUT引数は使えないので、以下のような記述になる 14 v_KANRI_NO := FNC_GET_NEXTVAL('KANRI_ID', v_SQLERR_CD, v_SQLERR_MSG) ; 15 -- ここにエラーの時のエラー表示と以下のINSERTはしない処理が欲しい 16 INSERT INTO TEST_TABLE_B VALUES (v_KANRI_NO, :NEW.FIELD_A, :NEW.FIELD_B); 17 END IF; 18END; 19/

連番を取得したいだけなら欠番を許容できるなら SEQUENCEを使います。
Oracle12.1以降なら CREATE TABLE文で連番を設定する こともできます。

投稿2018/08/09 20:02

編集2018/08/09 20:31
Orlofsky

総合スコア16415

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.51%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問