私の会社では、自動化された操作を実行するための大きなデータベースがあります。私たちがそのデータの小さなサンプルを得たことをテストするために、約10MBサイズのcsvファイルが6個あります。私たちは、H2を使ってプログラムの結果をテストしたいと思っています。 H2彼らは、せいぜい1000エントリの長さでしたが、私たちの以前のCVでうまく動作していたようです。それが私たちの10メガバイトのいずれかになるとレジストリの一つは、おそらく複製され、私たちの主キー制約を傷つけるされているので、コマンド大きなデータセットをh2データベースにロードできません
insert into myschema.mytable (select * from csvread('mycsvfile.csv'));
は失敗を報告したファイル。問題は、(数がどのデータIが使用さによって異なるが)挿入約10000行の後に現れ始めることを私が見ることができた小さな部分にmycsvfile.csvを破る
Unique index or primary key violation: "PRIMARY_KEY_6 ON MYSCHEMA.MYTABLE(DATETIME, LARGENUMBER, KIND)"; SQL statement:
insert into myschema.mytable (select * from csvread('src/test/resources/h2/data/mycsvfile.csv')) [23001-148] 23001/23001
。ただし、ファイルを分割して個別にコマンドを実行すると、10000行以上を挿入することができます。しかし、私が手動ですべてのデータを挿入することができたとしても、データベースを埋めるための自動化された方法が必要です。
このコマンドを実行しても、問題を引き起こしていた行が表示されないため、問題はcsvreadルーチンのキャッシュになる可能性があります。
次に、H2データベースにデータを手動で挿入できる小さなJavaプログラムを作成しました。私がコマンドをバッチするかどうかにかかわらず、1000行の接続をクローズしてオープンしました。h2は、データベースのエントリを複製しようとしていると報告しました。
私はdatetime型の列がデータセット全体で一意であるとして、レジストリが重複していないことを見つけることができるのemacsを使用してそのレジストリのための通常の検索を行うorg.h2.jdbc.JdbcSQLException: Unique index or primary key violation: "PRIMARY_KEY_6 ON MYSCHEMA.MYTABLE(DATETIME, LARGENUMBER, KIND)"; SQL statement:
INSERT INTO myschema.mytable VALUES ('1997-10-06 01:00:00.0',25485116,1.600,0,18) [23001-148]
。
私は、会社がその情報を販売しているので、あなたにテスト用のデータを与えることはできません。しかし、ここで私のテーブル定義はどのようになっています。
create table myschema.mytable (
datetime timestamp,
largenumber numeric(8,0) references myschema.largenumber(largecode),
value numeric(8,3) not null,
flag numeric(1,0) references myschema.flag(flagcode),
kind smallint references myschema.kind(kindcode),
primary key (datetime, largenumber, kind)
);
これが私たちのCSVファイルをどのように見えるかです:
datetime,largenumber,value,flag,kind
1997-06-11 16:45:00.0,25485116,0.710,0,18
1997-06-11 17:00:00.0,25485116,0.000,0,18
1997-06-11 17:15:00.0,25485116,0.000,0,18
1997-06-11 17:30:00.0,25485116,0.000,0,18
そして、我々のテストデータベースは、(私の醜いコードを許して埋めるだろうJavaコード、私は絶望的だ:)
private static void insertFile(MyFile file) throws SQLException {
int updateCount = 0;
ResultSet rs = Csv.getInstance().read(file.toString(), null, null);
ResultSetMetaData meta = rs.getMetaData();
Connection conn = DriverManager.getConnection(
"jdbc:h2:tcp://localhost/mytestdatabase", "sa", "pass");
rs.next();
while (rs.next()) {
Statement stmt = conn.createStatement();
StringBuilder sb = new StringBuilder();
for (int i = 0; i < meta.getColumnCount(); i++) {
if (i == 0)
sb.append("'" + rs.getString(i + 1) + "'");
else
sb.append(rs.getString(i + 1));
sb.append(',');
}
updateCount++;
if (sb.length() > 0)
sb.deleteCharAt(sb.length() - 1);
stmt.execute(String.format(
"INSERT INTO myschema.mydatabase VALUES (%s) ",
sb.toString()));
if (updateCount == 1000) {
conn.close();
conn = DriverManager.getConnection(
"jdbc:h2:tcp://localhost/mytestdatabase", "sa", "pass");
updateCount = 0;
}
}
if (!conn.isClosed()) {
conn.close();
}
rs.close();
}
リクエストされた場合、より多くの情報を提供できることをうれしく思います。
EDIT私が挿入されることに失敗したファイルからすべてのデータを削除するルーチンを持っているコマンドを実行する前に、私のJavaプログラムでデータベースがクリーンであるならば、私は常にチェック@Randy
。
Javaコードにデバッグプリントアウトを追加して、エラーの原因となっている行を正確に指定できます。次に、既存のレコードのためにデータベース(ソースファイルではない)をチャックします。たぶんあなたは日付の切り捨てを取得していますか? – Randy
プライマリキー制約なしでテーブルを作成して、それを実行してください: '日時、大番号、種別がcount(*)> 1のmytableグループからdatetime、largeenumber、kind、count(*)を選択してください。問題の根本的な原因を簡単に見つけて、それらの行を分析します。ところで、 'create table ... as select ...'という文を使うと、 'create table'と' insert'の2つの文よりも速くなります。 –