2017-12-14 12 views
0

FORALLを使用してBULKデータを挿入する機能があります。Oracle関数の入力パラメータとして配列を渡す方法

create or replace type l_array_tab as table of number; 

create or replace FUNCTION fn_insert_using_array(
    L_TAB   VARCHAR2, 
    L_COL_NAME VARCHAR2, 
    L_ARRAY L_ARRAY_TAB) 
    RETURN NUMBER 
AS 
    SQL_STMT VARCHAR2(32767); 
    sql_count NUMBER; 
BEGIN 
    FORALL i IN L_ARRAY.first .. L_ARRAY.LAST 

     EXECUTE immediate 'INSERT INTO my_table 
       Select * from '||L_TAB 
       ||' where '||L_COL_NAME||' := :1' using L_ARRAY(i); 
     sql_count:= SQL%ROWCOUNT; 

    RETURN SQL_COUNT; 
end; 

この例では、この関数を別のストアドプロシージャまたはplsqlブロックから呼び出す必要があります。この関数を呼び出す際に、間違った番号や型の入力としてエラーが発生しています。

create or replace type l_array_orig_tab as table of number; 

Declare 
    l_array_orig l_array_orig_tab :=l_array_orig_tab(); 
    l_tab varchar2(30): ='my_tab_orig'; 
    l_col_name varchar2(30) :='insert_id'; 
    V_COUNT NUMBER; 
    cursor c1 is select * from my_tab_orig; 
begin 
    open c1; 
    LOOP 
     FETCH c1 BULK COLLECT INTO l_array_orig limit 1000; 
     EXIT WHEN L_ARRAY_orig.COUNT =0; 
     V_COUNT:= fn_insert_using_array(L_TAB, L_COL_NAME,l_array_orig); 
    END LOOP; 
END ; 

機能を呼び出す方法を提案してください:

これは私が関数を呼び出しています方法です。

答えて

0

は私が間違った番号または入力

l_array_orig_tabl_array_tab異なるタイプがあるので、あなたがエラーを取得しているの種類としてエラーを取得しています。オラクルが異なるタイプであることが分かっている限り、同じ構造を持つことは重要ではありません。 Oracleはデータベース・エンジンであり、型の安全性を強く強制します。ここにはno duck typingがあります。

ので、最も簡単な解決策は、関数を呼び出すときに正しい型を使用することです:

Declare 
    l_array_orig l_array_tab :=l_array_tab(); -- change this declaration 
    l_tab varchar2(30): ='my_tab_orig'; 
    l_col_name varchar2(30) :='insert_id'; 
    V_COUNT NUMBER; 
    cursor c1 is select * from my_tab_orig; 
begin 
    open c1; 
    LOOP 
     FETCH c1 BULK COLLECT INTO l_array_orig limit 1000; 
     EXIT WHEN L_ARRAY_orig.COUNT =0; 
     V_COUNT:= fn_insert_using_array(L_TAB, L_COL_NAME,l_array_orig); 
    END LOOP; 
END ; 

「機能fn_insert_using_arrayが異なるスキーマともタイプです。」

したがって、関数を所有するスキーマから、関数に対するEXECUTE権限が付与されています。しかし、彼らはまたあなたにそのタイプのEXECUTEを与える必要があります。これは彼らの責任です。UDTを署名に入れて関数を定義したので、呼び出すために必要なすべての特権を与える必要があります。

これはSOに投稿するためのおもちゃの例ではありませんが、そうでない場合はこのようなタイプを作成する必要はありません。代わりに、文書化されたOracle組み込みの数値表sys.odcinumberlistを使用してください。

+0

こんにちは..お返事ありがとうございます。ファンクションfn_insert_using_arrayは、別のスキーマにあり、タイプも同じです。他のスキーマからタイプを使用することができます。私は実際に関数を次のように呼び出しています。 V_COUNT:= other_user.fn_insert_using_array(L_TAB、L_COL_NAME、l_array_orig);そこで私は同じ構造の2つのタイプを作成しました。それぞれのスキーマに1つずつあります。 – Abhi

0

l_array_orig_tab!= l_array_tab タイプ間で同じタイプを使用するか、タイプ間でキャストを行う必要があります。

Declare 
l_array_orig l_array_orig_tab; 
new_array l_array_tab; 
l_tab varchar2(30): ='my_tab_orig'; 
l_col_name varchar2(30) :='insert_id'; 
V_COUNT NUMBER; 
cursor c1 is select * from my_tab_orig; 
begin 
open c1; 
LOOP 
FETCH c1 BULK COLLECT INTO l_array_orig limit 1000; 
select cast(l_array_orig as l_array_tab) into new_array from dual; 
EXIT WHEN L_ARRAY_orig.COUNT =0; 
V_COUNT:= fn_insert_using_array(L_TAB, L_COL_NAME,new_array); 
END LOOP; 
END ; 

キャストの仕組み。
select cast(variable as destination_type) into var_destination_type from dual

+0

こんにちは..お返事ありがとうございます。ファンクションfn_insert_using_arrayは、別のスキーマにあり、タイプも同じです。他のスキーマからタイプを使用することができます。私は実際に関数を呼び出しています:V_COUNT:= other_user.fn_insert_using_array(L_TAB、L_COL_NAME、l_array_orig);そこで私は同じ構造の2つのタイプを作成しました。それぞれのスキーマに1つずつあります。 – Abhi

関連する問題