2

bytea の配列をストアド プロシージャ (bytea[] の場合は宣言された型) に渡す必要があります。

データはストアド プロシージャに渡されますが、bytea[] から個々のバイトを取得できません。array_lower および array_upper 関数は 1 次元を報告しますが、tumb_data[1] は常に NULL を返します。

ストアド プロシージャから bytea[] オブジェクト全体を出力すると、「{{-1,-40,-1,-32,0,16,74,70,73,70,0,1」で始まるものが得られます、1」なので、データが手順に到達していることがわかります。

これは、問題を示すコードの例です。

Class.forName("org.postgresql.Driver");
String url = "jdbc:postgresql://localhost/test";
Connection c = DriverManager.getConnection(url,"andres","xxx");
List<byte[]> thumbData=new ArrayList<byte[]>();
thumbData.add("Test #1".getBytes());
thumbData.add("Test #1".getBytes());
Object[] thumbs=thumbData.toArray();
Array thumbArray=c.createArrayOf("bytea", thumbs);
PreparedStatement stmt=c.prepareStatement("SELECT test_funct(?)");
stmt.setArray(1,thumbArray);
stmt.execute();

そして、これはストアド プロシージャです。

CREATE OR REPLACE FUNCTION test_funct(a_bytes bytea[])
  RETURNS boolean AS
$BODY$DECLARE
    v_bytes bytea;
BEGIN
FOR i IN array_lower(a_bytes,1) .. array_upper(a_bytes,1) LOOP 
        v_bytes:= a_bytes[i];
        IF (v_bytes IS NULL) THEN
            RAISE EXCEPTION 'error';
        END IF; 
    END LOOP;

    RETURN true;
END$BODY$
  LANGUAGE plpgsql VOLATILE
  COST 100;

最後に、テスト プログラムを実行したときのログ出力を次に示します。

2013-02-17 21:03:52 EST LOG:  execute <unnamed>: SET extra_float_digits = 3
2013-02-17 21:03:52 EST LOG:  execute <unnamed>: SELECT oid FROM pg_catalog.pg_type WHERE typname = $1
2013-02-17 21:03:52 EST DETAIL:  parameters: $1 = '_bytea'
2013-02-17 21:03:52 EST LOG:  execute <unnamed>: SELECT e.typdelim FROM pg_catalog.pg_type t, pg_catalog.pg_type e WHERE t.oid = $1 and t.typelem = e.oid
2013-02-17 21:03:52 EST DETAIL:  parameters: $1 = '1001'
2013-02-17 21:03:52 EST LOG:  execute <unnamed>: SELECT test_funct($1)
2013-02-17 21:03:52 EST DETAIL:  parameters: $1 = '{{"\\x3834","\\x313031","\\x313135","\\x313136","\\x3332","\\x3335","\\x3439"},{"\\x3834","\\x313031","\\x313135","\\x313136","\\x3332","\\x3335","\\x3439"}}'
2013-02-17 21:03:52 EST ERROR:  error
2013-02-17 21:03:52 EST STATEMENT:  SELECT test_funct($1)
2013-02-17 21:03:52 EST LOG:  unexpected EOF on client connection

これを私のストアドプロシージャに渡す方法はありますか?

4

1 に答える 1

2

あなたの配列には 2 つの次元があると思われます。の 1 次元 (線形) 配列ではbyteaなく、 の 2 次元配列がありbyteaます。このような配列の最初の次元にインデックスを付けると、空の結果が生成されます。どの次元の PostgreSQL 配列にも基本的な配列データ型があることに注意してbytea[][]ください。などはありません。array_ndims(anyarray)配列の次元を取得するために使用します。

一次元を観察する:

WITH t1(ba) AS (VALUES(ARRAY[ '\x0a', '\x0c', '\x0e' ] :: bytea[]))
SELECT ba, ba[1], ba[1][1] FROM t1;
            ba             |  ba  | ba 
---------------------------+------+----
 {"\\x0a","\\x0c","\\x0e"} | \x0a | 
(1 row)

対二次元:

WITH t1(ba) AS (VALUES(ARRAY[[ '\x0a', '\x0c', '\x0e' ]] :: bytea[]))
SELECT ba, ba[1], ba[1][1] FROM t1;

             ba              | ba |  ba  
-----------------------------+----+------
 {{"\\x0a","\\x0c","\\x0e"}} |    | \x0a
(1 row)

完全な値または SQL を示していないため、これ以上のことは言えません。

JDBC ドライバーの問題が疑われる場合は、テスト データベースをセットアップするための SQL スクリプトを含む、問題を実証した自己完結型のコンパイル可能なテスト ケースを提供していただけると助かります。

渡されたパラメータを含めて実行される実際の SQL を表示してください。これは、有効になっている PostgreSQL ログ ファイルから取得できますlog_statement

于 2013-02-17T12:30:44.630 に答える