- PR -

同じ結果を返すResultsetなのに変更可否が分かれるのは何故?

投稿者投稿内容
夕飯のおかず
会議室デビュー日: 2006/01/25
投稿数: 8
投稿日時: 2006-01-27 13:44
現在、PostgreSQL 8.1.1 + postgresql-8.1-404.jdbc3.jarを利用してデータベースからデータを取得する処理を記述しています。

Statement st = con.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE);
ResultSet rs = st.executeQuery(sql);

仮に2つのテーブルtbl1のcol2とtbl2.colを結合した結果を得たい場合、今まで上記のsql変数に

select * from tbl1,tbl2 where tbl1.col2 = tbl2.col1

としていた(はず?)なのですが、このSELECT文だと
PSQLException: No primary key found for table t_user,.
が帰ってきます。しかし

select * from tbl1 inner join tbl2 on tbl1.col2 = tbl2.col1

とすると、Exceptionは吐きません。それぞれ同じ結果を返すものと認識していましたが、実際には違うものなのでしょうか?それとも、これはJDBCドライバやデータベースのバージョンに依存する問題なのでしょうか?Database会議室に書き込むべき内容か悩みましたがこちらにて質問させていただきました。悪しからずご了承ください。




山本 裕介
ぬし
会議室デビュー日: 2003/05/22
投稿数: 2415
お住まい・勤務地: 恵比寿
投稿日時: 2006-01-27 14:32
psql をつかってクエリを投げてみてはいかがでしょう。
同じ結果であれば PosrgreSQL 自体の問題(?)ですし、違う結果になれば JDBC なり Java のレベルで何かが起こっているということになりますね。
夕飯のおかず
会議室デビュー日: 2006/01/25
投稿数: 8
投稿日時: 2006-01-27 16:02
psqlやpgAdminで見てみた限りでは、どちらも結果に変わりはないように見えます。

やはりPostgreSQL側の問題なのでしょうか。

山本 裕介
ぬし
会議室デビュー日: 2003/05/22
投稿数: 2415
お住まい・勤務地: 恵比寿
投稿日時: 2006-01-27 16:08
そうですね。psqlなどでも再現できるのであれば Java や JDBC とは独立した問題と考えて良いのではないでしょうか。
今川 美保(夏椰)
ぬし
会議室デビュー日: 2004/06/10
投稿数: 363
お住まい・勤務地: 神奈川県茅ヶ崎市
投稿日時: 2006-01-27 16:55
う〜〜ん?

自環境
WinXP SP2
Java 1.5
PostgreSQL Database Server 8.1
postgresql-8.1-404.jdbc3.jar

でやってみたところ、どちらも正常にSelectできましたよ。

=======================================================
( 以下テスト環境 )

テーブル定義
コード:
CREATE TABLE test1
(
  keycol char(3) NOT NULL,
  value varchar,
  CONSTRAINT "Test1PK" PRIMARY KEY (keycol)
) 
WITHOUT OIDS;

CREATE TABLE test2
(
  keycol char(3) NOT NULL,
  value varchar,
  CONSTRAINT "Test2PK" PRIMARY KEY (keycol)
) 
WITHOUT OIDS;



テストデータ
コード:
----test1----
keycol1:value
"000";"test0"
"002";"test0"
"003";"test0"
"004";"test0"
"005";"test0"
"006";"test0"
"007";"test0"
"008";"test0"
"009";"test0"
"010";"test0"

----test2----
"000";"test0"
"002";"test0"
"003";"test0"
"004";"test0"
"005";"test0"
"006";"test0"
"007";"test0"
"008";"test0"
"009";"test0"
"010";"test0"




実験ソースコード
コード:
import java.sql.* ;

public class test {

  public static void main(String[] args) {
	try {
      Class.forName("org.postgresql.Driver");

      Connection con =
        DriverManager.getConnection("jdbc:postgresql:Test",
                                    "postgres",
                                    "postgres");

      Statement stmt = con.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE);


      String sql = "select * from test1, test2 where test1.keycol = test2.keycol ;";
      //String sql = "select * from test1, test2 where test2.keycol = test1.keycol ;";
      //String sql = "select * from test1 join test2 on test1.keycol = test2.keycol ;";
      //String sql = "select * from test1 join test2 on test2.keycol = test1.keycol ;";

      ResultSet rs = stmt.executeQuery(sql);
      while(rs.next()){
        String lang = rs.getString("keycol");
        System.out.println(lang);
      }
      // データベースから切断
      stmt.close();
      con.close();
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
}



冬寂
ぬし
会議室デビュー日: 2002/09/17
投稿数: 449
投稿日時: 2006-01-27 18:31
引用:

PSQLException: No primary key found for table t_user,.


とある通り、primary key を設定すればエラーは出なくなると思いますよ。

ただ、なぜ primary key が無くても inner join の場合には通るのか?というと分かりません。
(primary key が無いとレコードの識別が出来なくなるので、postgres の仕様/バグなのかもしれません。)
今川 美保(夏椰)
ぬし
会議室デビュー日: 2004/06/10
投稿数: 363
お住まい・勤務地: 神奈川県茅ヶ崎市
投稿日時: 2006-01-27 19:21
引用:

冬寂さんの書き込み (2006-01-27 18:31) より:
引用:

PSQLException: No primary key found for table t_user,.


とある通り、primary key を設定すればエラーは出なくなると思いますよ。

ただ、なぜ primary key が無くても inner join の場合には通るのか?というと分かりません。
(primary key が無いとレコードの識別が出来なくなるので、postgres の仕様/バグなのかもしれません。)



この書き込みを見て 主キー設定をはずして同じプログラムを動かしても
データがちゃんと取れました。

PostgreSQLのバグデータベース?見ていたら
同様の事象が発生していました。(バージョンが違いますが・・・)
http://archives.postgresql.org/pgsql-jdbc/2004-01/msg00190.php
記事の日付が2004なので、私が使用したバージョンでは修正されていたんですかね・・・?
#今月に落とした最新のPostgreSQLを使用しているので・・・。


[ メッセージ編集済み 編集者: 夏椰|。σ)o 編集日時 2006-01-27 19:23 ]
冬寂
ぬし
会議室デビュー日: 2002/09/17
投稿数: 449
投稿日時: 2006-01-28 10:06
引用:

夏椰|。σ)oさんの書き込み (2006-01-27 19:21) より:
この書き込みを見て 主キー設定をはずして同じプログラムを動かしても
データがちゃんと取れました。


うちでもちょっと試してみました・・・が、見事にデータ取れてましたね^^;
(うちでは Java の環境が無いので、PHP と psql で検証してみました。)

ただ、「primary key が無いのに、どうやってレコードを識別するの?」と考えると難しい問題になると思うので、
もし、スレ主さんの問題が primary key を設定する事で解決するのなら、それでいいのではないかなぁ、と。。。
(どうやってレコードを識別する?というのを、postgresで解決しようとしたり、JDBC で解決しようとしたり・・・って考えると複雑になりますからね)

スキルアップ/キャリアアップ(JOB@IT)