1

http://docs.oracle.com/javase/1.4.2/docs/guide/jdbc/getstart/preparedstatement.htmlから次のコード例を取得しました

3 つの質問があります。

  1. LAST、FIRST、HOMEの3つの列しかないことを考えると、「keyColumn」は何を指しますか。
  2. 生成されたキーの繰り返しにループが使用されるのはなぜですか? その 1 つの挿入ステートメントに対して複数の行が返されますか?
  3. テーブルごとに複数の生成されたキーをサポートするデータベースはどれですか?
String sql = "INSERT INTO AUTHORS (LAST, FIRST, HOME) VALUES " +
                                     "(?, ?, ?, keyColumn)";

PreparedStatement addAuthor = con.prepareStatement(sql,
                             Statement.RETURN_GENERATED_KEYS);
addAuthor.setString(1, "Wordsworth");
addAuthor.setString(2, "William");
addAuthor.setString(3, "England");

int rows = addAuthor.executeUpdate();

ResultSet rs = stmt.getGeneratedKeys();
if (rs.next()) {
    ResultSetMetaData rsmd = rs.getMetaData();
    int colCount = rsmd.getColumnCount();
    do {
        for (int i = 1; i <= colCount; i++) {
            String key = rs.getString(i);
            System.out.println("key " + i + "is " + key);
        }
    }
    while (rs.next();)
} 
else {
    System.out.println("There are no generated keys.");
}
4

1 に答える 1

3

keyColumn質問 1.リンクのクエリでは、単に例のエラーだと思います。その段落の 2 番目と 3 番目の例にも、重大な構文エラーが含まれています。私はそれにこだわるつもりはありません。このドキュメントは、最近の Java バージョンから完全に削除されました。

質問 2.複数の挿入行を生成できるINSERT INTO ... SELECT ... FROM ...orのようなステートメントについて考えてください。INSERT INTO ... VALUES (...), (...)また、一部のデータベースは他の DML から値を返すことをサポートしています (例: UPDATEor DELETE)。これは複数の行にも影響を与える可能性があるため、ループを考慮する必要があります。この特定の例では、1 行だけが挿入されることが確実であるため、これは必要ありません。

質問 3. この質問はもう少し複雑です。

一部のデータベース (またはドライバー) は、実際に生成された列が何であるかを簡単に判断できません。たとえば、データベースにはIDENTITY列がありませんが、トリガーを使用してキーを生成するためです。生成されたキーを識別するには、テーブルのすべてのトリガーを解析して、生成された値が (主キーまたはその他の) 列に割り当てられているかどうかを確認する必要がありますが、これは簡単には実行できず、エラーが発生しやすくなります。また、複数の生成された列 (計算フィールドなど) が存在する場合もあります。開発者は、取得できるフィールド、または取得したいフィールドを知っている必要があります。

どのフィールドを返すかを決定するのは難しい (または非効率的) ため、一部のドライバーは (デフォルトで) 挿入 (または削除/更新) 行のすべての列を返します。たとえば、PostgreSQL および Firebird ドライバーはそれを行います。一方、一部のドライバーは、テーブルに ID 列が含まれていなくても、最後に生成されたキーを返すだけです (MySQL には含まれていると思いますが、100% 確実ではありません)。そして、Oracle ドライバーは単純に を返し、ROWIDそれを使用してデータベースから実際の値を取得するのはユーザーに任されていることを覚えているようですROWID

返される列が明確にわかっている場合は、列の序数インデックスまたは列名の配列を受け入れる代替メソッドを使用して、自分で指定できます。ただし、すべてのドライバーがそれをサポートしているわけではありません。

于 2012-11-03T10:00:49.397 に答える