2

DB2を使用してネストされた構造化タイプ(UDT)を使用しようとしていますが、いくつかの問題が発生しました。

以下は、ユースケースの型、テーブル、関数、および変換を作成するためのSQLステートメントです。すべてのステートメントは正常に実行されますが、単純な実行を試みるとエラーが発生します select * from t_author

CREATE TYPE u_street_type AS (
  street VARCHAR(100),
  no VARCHAR(30)
) INSTANTIABLE MODE DB2SQL;

CREATE TYPE u_address_type AS (
  street u_street_type,
  zip VARCHAR(50),
  city VARCHAR(50),
  country VARCHAR(50),
  since DATE,
  code INT
) INSTANTIABLE MODE DB2SQL;

CREATE TABLE t_author (
  ID INT NOT NULL PRIMARY KEY,
  FIRST_NAME VARCHAR(50),
  LAST_NAME VARCHAR(50) NOT NULL,
  DATE_OF_BIRTH DATE NOT NULL,
  YEAR_OF_BIRTH INT,
  ADDRESS u_address_type
);

CREATE FUNCTION f_u_street_type_transform (street u_street_type) 
  RETURNS ROW (
    street VARCHAR(100), 
    no VARCHAR(30)
  )
  LANGUAGE SQL
  RETURN VALUES (
    street..street, 
    street..no
  );

CREATE TRANSFORM FOR u_street_type db2_program 
  (FROM SQL WITH FUNCTION f_u_street_type_transform);

CREATE FUNCTION f_u_address_type_transform (address u_address_type)
  RETURNS ROW (
    street VARCHAR(100),
    no VARCHAR(30),
    zip VARCHAR(50),
    city VARCHAR(50),
    country VARCHAR(50),
    since DATE,
    code INT
  )
  LANGUAGE SQL
  CONTAINS SQL
  NO EXTERNAL ACTION
  DETERMINISTIC
  RETURN VALUES (
    address..street..street,
    address..street..no,
    address..zip,
    address..city,
    address..country,
    address..since,
    address..code
  );

CREATE TRANSFORM FOR u_address_type db2_program 
  (FROM SQL WITH FUNCTION f_u_address_type_transform);

次のエラーが発生しますselect * from t_author;

The function "F_U_ADDRESS_TYPE_TRANSFORM" resolved to specific function 
"SQL101230131003100" that is not valid in the context where it is used.. 
SQLCODE=-390, SQLSTATE=42887, DRIVER=3.57.82

私が間違っていることについて何か考えはありますか?

DB2 v9.5(Linux)を使用しています。

4

3 に答える 3

4

問題は、列 ADDRESS の各値がスカラー値であることです。「SELECT * FROM t_author」のようなクエリがあるために、構造化された型の値をクライアント アプリケーション (DB2 CLP など) にバインドする場合は、構造化された値をタイプ VARCHAR、CLOB、または必要なものの単一の値。複数の列のようなものにする必要があるため、変換関数を使用して複数の値に展開することはできません。(そして、異なる変換関数が異なる数の値を返す可能性があり、クエリのスキーマが完全に異なる可能性があるため、これは不可能です。まったく同じクエリを別のセマンティクスを持つサブクエリとして使用する場合の問題は言うまでもありません。)

複数の列を持つ ROW() を返す変換関数は、構造化された型の値を外部 UDF (C/C++ または Java で記述) と交換する場合にのみ使用できます。

ps: 私のお勧めは、通常の正規化されたリレーショナル データベース設計を使用し、構造化された型を避けるようにすることです。

于 2010-12-30T13:03:14.187 に答える
2

DB2の観点からは、jOOQは単なるデータベースアプリケーションです。したがって、データベースアプリケーションに関するすべての考慮事項は、データベースアプリケーションにも関連しています。つまり、jOOQは、変換関数としてスカラー関数を持つ変換グループも使用する必要があります。私が知っている組み込みのサポートはありません。

あなたにできることは:

  • 個別のパラメーターを入力として受け取り、それらをBLOBに連結する外部関数を作成します。次に、jOOQはBLOBを分解し、それぞれのJavaオブジェクトを構築します
  • 構造化タイプをXMLドキュメントに変換すると、jOOQはXMLドキュメントを解析し、Javaオブジェクトを構築します

つまり、DB2とアプリケーションの間で転送される値の構造情報を自分で保持するように注意する必要があります。また、アプリケーションは、それに応じてデータ自体も同様に解釈する必要があります。したがって、タイプ固有のコードを何らかの方法で生成するのは、すべて手動のタスクです。

残念ながら、リレーショナルデータベースシステムのOO機能は、一般的に、本当に簡単でシームレスに使用できるほどには進んでいません。簡単には使用できないため、構造化型を使用するアプリケーションはごくわずかです。また、ユーザー数が少ないため、その分野での改善は優先度が高くありません。

于 2011-01-04T12:08:22.330 に答える
1

有益な答えをありがとうKnut!

クライアントアプリケーション(つまり)を使用するときに、構造化された値を単一の値に変換するスカラー変換関数を使用する必要があることを理解していますselect * from t_author。構造化された値の要素を単一のvarchar値に連結する変換関数を作成することで、これを管理しました。

これにより、クライアントアプリケーションからデータを取得する際の問題が解決されますが、これを機能させる本当の理由は、データベースインターフェイスライブラリjOOQで構造化型をサポートしようとしているときです。このライブラリテーブルを使用すると、列、ストアドプロシージャ、関数、構造化タイプなどが、生成されたJavaクラスとしてモデル化されます。

java.sql.Structを使用してjava.sql.ResultSetの構造化値列からデータを取得し、生成されたJavaクラスに値を入力することを考えていました。

変換関数で構造体型をvarchar値に変換したときに、java.sql.Structを使用してデータを取得できましたが、これは私が望むものではありません。構造化タイプの個々の要素に「直接」アクセスしたい。

これを達成するためのヒントはありますか?

于 2011-01-04T11:23:07.617 に答える