6

かなり複雑なストアド プロシージャとして始まったものは、非常に単純なユース ケースに要約され、期待どおりに機能していないようです。

私のテストでは、ストアド プロシージャは次のようになります。

CREATE OR REPLACE PROCEDURE proc_test(
v_someString varchar2
                      ) as
BEGIN
    dbms_output.put_line('test');
END;

呼び出し可能なステートメント API を使用して、Java からこのストアド プロシージャを呼び出すことができます。

java.sql.CallableStatement stmt = conn.prepareCall("call proc_test(?)");
stmt.setObject(1,null);
stmt.execute();

上記は期待どおりに機能します。メソッドが実行され、正常に完了します。ここがトリッキーになります。次のようなより複雑な構造を渡すことができるように、オラクル オブジェクト タイプのセットを作成しました。

CREATE OR REPLACE
type SOMETYPE_TYPE force  UNDER BASE_TYPE (value varchar2(255),
CONSTRUCTOR FUNCTION SOMETYPE_TYPE RETURN SELF AS RESULT) NOT FINAL;

次のように、これらの型をパラメーターとして受け入れるように手順を変更するだけです。

CREATE OR REPLACE PROCEDURE proc_test(
v_someString SOMETYPE_TYPE 
                      ) as
BEGIN
    dbms_output.put_line('test');
END;

オラクルは壊れますPLS-00306: wrong number or types of arguments in call to 'CNV_CREATE_PERSON'

何を与える?null を値として別のプロシージャからこのプロシージャを呼び出すと、正常に動作します。Java API から呼び出すだけで壊れます。

解決策についてドキュメントを精査してきましたが、見つかりません。おそらく、賢明で学識のある皆さんの 1 人が、私を正しい方向に向けてくれるかもしれません。

ありがとう

4

1 に答える 1

11

メソッドを使用してsetNull()、ユーザー定義型を指定する必要があります。

void setNull(String parameterName,
           int sqlType,
           String typeName)
             throws SQLException

指定されたパラメーターを SQL に設定しますNULL。このバージョンのメソッドsetNullは、ユーザー定義型および REF 型パラメーターに使用する必要があります。ユーザー定義型の例には、STRUCT、DISTINCT、JAVA_OBJECT、名前付き配列型などがあります。

: 移植可能にするために、アプリケーションは、NULL ユーザー定義パラメーターまたは REF パラメーターを指定するときに、SQL 型コードと完全修飾 SQL 型名を指定する必要があります。ユーザー定義型の場合、名前はパラメーター自体の型名です。REF パラメータの場合、名前は参照される型の型名です。

だからあなたの場合:

stmt.setNull(1, java.sql.Types.STRUCT, "SOMETYPE_TYPE");

渡すだけnullでは、それが表す型がわからず、暗黙的な変換を行うことができません。つまり、Java オブジェクトが null であるかどうかに応じてコードを分岐し、必要に応じて呼び出すsetNull()必要setObject()があるということです。

例にも実際に使用する必要がありますsetNull()が、次のように、より単純なバージョンを使用できます。varchar2

stmt.setNull(1, java.sql.Types.VARCHAR);

...しかし、あなたはただ通り過ぎるだけで逃げますnull

于 2014-09-08T17:43:19.083 に答える