1

そのため、Java を使用して SQL でデータベースを作成する作業を行っていますが、解決できない問題に直面し続けています。助けていただければ幸いです。次のコードを使用して、データをデータベースに読み込みます。現在、データベースに newTestTable2 という名前を付けています。このデータベースには、stockID (INT)、millisFromMid (INT)、bidPrice (DOUBLE)、askPrice (DOUBLE) の 4 つの列があります。ストックIDを主キーとして使用して、準備されたステートメントを使用してデータベースに新しい情報を追加しようとしていますが、多くの問題が発生しています。コードは次のとおりです。

import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.PreparedStatement;
import java.util.zip.GZIPInputStream;


public class ReadGZippedTAQQuotesFile {

    // Header fields

    protected int _secsFromEpoch;
    protected int _nRecs;

    // Record fields

    protected int   [] _millisecondsFromMidnight;
    protected int   [] _bidSize;
    protected float [] _bidPrice;
    protected int   [] _askSize;
    protected float [] _askPrice;

    public int getSecsFromEpoch () { return _secsFromEpoch; }
    public int getNRecs         () { return _nRecs;         }

    public int   getMillisecondsFromMidnight ( int index ) { return _millisecondsFromMidnight[ index ]; }
public int   getBidSize                  ( int index ) { return _bidSize[ index ];                  }
public float getBidPrice                 ( int index ) { return _bidPrice[ index ];                 }
public int   getAskSize                  ( int index ) { return _askSize[ index ];                  }
public float getAskPrice                 ( int index ) { return _askPrice[ index ];                 }

public static Connection connect = null;
public static PreparedStatement pst = null;
public static PreparedStatement pst1 = null;
public static PreparedStatement pst2 = null;
public static PreparedStatement pst3 = null;
public static ResultSet resultSet = null;

/**
 * Constructor - Opens a gzipped TAQ quotes file and reads entire contents into memory.
 * 
 * @param filePathName Name of gzipped TAQ quotes file to read
 * @throws IOException 
 */
public ReadGZippedTAQQuotesFile( File filePathName ) throws IOException {

    // Open file 

        InputStream in = new GZIPInputStream( new FileInputStream( filePathName ) );
        DataInputStream dataInputStream = new DataInputStream( in );

    // Read and save header info

        _secsFromEpoch = dataInputStream.readInt();
        _nRecs = dataInputStream.readInt();

    // Allocate space for data

        _millisecondsFromMidnight = new int   [ _nRecs ];
        _bidSize                  = new int   [ _nRecs ];
        _bidPrice                 = new float [ _nRecs ];
        _askSize                  = new int   [ _nRecs ];
        _askPrice                 = new float [ _nRecs ];

    // Read all records into memory

        for( int i = 0; i < _nRecs; i++ )
            _millisecondsFromMidnight[ i ] = dataInputStream.readInt();

        for( int i = 0; i < _nRecs; i++ )
            _bidSize[ i ] = dataInputStream.readInt();

        for( int i = 0; i < _nRecs; i++ )
            _bidPrice[ i ] = dataInputStream.readFloat();

        for( int i = 0; i < _nRecs; i++ )
            _askSize[ i ] = dataInputStream.readInt();

        for( int i = 0; i < _nRecs; i++ )
            _askPrice[ i ] = dataInputStream.readFloat();

    // Finished reading - close the stream

        dataInputStream.close();

}

/**
 * Example of using this class to read a TAQ quotes file and access
 * individual records.
 * @throws ClassNotFoundException 
 * @throws SQLException 
 */
public static void quotesReader() throws ClassNotFoundException, SQLException {
    File f = new File("/Users/Adam/Desktop/SQL Folder/20070620/20070620");
    File[] files = f.listFiles();

    try {

        // This will load the MySQL driver
        Class.forName("com.mysql.jdbc.Driver");

        // Setup the connection with the DB
        connect = DriverManager.getConnection( 
                "jdbc:mysql://localhost:3306/newTest", "root", "Kariya"
                );

        // Statements allow us to issue SQL queries to the database
        pst = connect.prepareStatement("INSERT INTO newTestTable2(stockID) VALUES(?)");
        pst1 = connect.prepareStatement("INSERT INTO newTestTable2(millisFromMid) VALUES(?)");
        pst2 = connect.prepareStatement("INSERT INTO newTestTable2(bidPrice) VALUES(?)");
        pst3 = connect.prepareStatement("INSERT INTO newTestTable2(askPrice) VALUES(?)");

        // Read entire TAQ quotes file into memory

        pst.setInt(1, 0);
        pst.executeUpdate();

        for( int i=0; i < files.length; i++) {
            ReadGZippedTAQQuotesFile taqQuotes = new ReadGZippedTAQQuotesFile( files[i] );

            pst.setInt(1, i+1);
            pst.executeUpdate();

            // Iterate over all records, writing the contents of each to the console

            int nRecs = taqQuotes.getNRecs();
            for( int j = 0; j < nRecs; j++ ) {

                pst1.setInt(1, taqQuotes.getMillisecondsFromMidnight( j ));
                pst1.executeUpdate();
                pst2.setDouble(1, taqQuotes.getBidPrice( j ));
                pst2.executeUpdate();
                pst3.setDouble(1, taqQuotes.getAskPrice( j ));
                pst3.executeUpdate();

                /*

                System.out.println(
                        taqQuotes.getMillisecondsFromMidnight( j )
                        + ","
                        + taqQuotes.getBidSize( j )
                        + ","
                        + taqQuotes.getBidPrice( j )
                        + ","
                        + taqQuotes.getAskSize( j )
                        + ","
                        + taqQuotes.getAskPrice( j )
                        );

                */
            }
        }
    } catch (IOException e1) {
        e1.printStackTrace();
    } finally {
        try {
            if (pst != null) {
                pst.close();
            }
            if (pst1 != null) {
                pst1.close();
            }

            if (pst2 != null) {
                pst2.close();
            }

            if (pst3 != null) {
                pst3.close();
            }

            if (connect != null) {
                connect.close();
            }
        } catch (Exception e) {

        }
    }
}

public static void main( String[] args ) throws ClassNotFoundException, SQLException {
    quotesReader();
}

}

次の例外が発生します

 Exception in thread "main"
  com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException:
  Duplicate entry '0' for key 'PRIMARY'"

したがって、同じ株式 ID を何度も使用していると言っていることは理解していますが、次のような行を使用しない場合:

pst.setInt(1, 0);
pst.executeUpdate();

次に、デフォルト値がないことを返しますがstockID、INT のデフォルト値は 0 である必要があるため、これも奇妙に思えます。このコードは正しい近隣にあるはずですが、このエラーの原因がわかりません。誰でも洞察を共有できますか?

4

3 に答える 3

1

本当に 4 つの準備済みステートメントが必要ですか? taqQuotes ごとに 1 行のデータを挿入する必要がありますか? もしそうなら、私は次のようにします:

public static void quotesReader() throws ClassNotFoundException, SQLException {
  File f = new File("/Users/Adam/Desktop/SQL Folder/20070620/20070620");
  File[] files = f.listFiles();

  try {
    Class.forName("com.mysql.jdbc.Driver");
    connect = DriverManager.getConnection( 
            "jdbc:mysql://localhost:3306/newTest", "root", "Kariya"
            );
    long counter = 1; // place this before the for(int i=0...) loop
    pst = connect.prepareStatement("INSERT INTO newTestTable2(stockID, millisFromMid, bidPrice, askPrice) VALUES(?,?,?,?)");

    for( int i=0; i < files.length; i++) {
      ReadGZippedTAQQuotesFile taqQuotes = new ReadGZippedTAQQuotesFile( files[i] );
      int nRecs = taqQuotes.getNRecs();
      for( int j = 0; j < nRecs; j++ ) {
        pst.setInt(1, counter++);
        pst.setInt(2, taqQuotes.getMillisecondsFromMidnight( j ));
        pst.setDouble(3, taqQuotes.getBidPrice( j ));
        pst.setDouble(4, taqQuotes.getAskPrice( j ));
        pst.executeUpdate();
      }
    }
  } catch (IOException e1) {
    e1.printStackTrace();
  } finally {
    try {
        if (pst != null) {
            pst.close();
        }
        if (connect != null) {
            connect.close();
        }
    } catch (Exception e) {

    }
  }
}

これにより、1 つの列のみが入力された 4 つのレコードではなく、taqQuotes ごとに 1 つのレコードが挿入されます。

于 2012-12-27T03:09:56.383 に答える
0

ここでの問題は、stockID を主キーとして使用すると同時に、stockID を使用して個々の株式を識別したかったことです。在庫ごとに数百行のデータがあったため、これは機能しません。そのため、繰り返すことができるように在庫 ID が必要でした。上記の誰もが指摘したように、主キーは一意である必要があります。JScoobyCed によって提案された方向を試みたところ、コードを少しきれいにするのに本当に役立ちましたが、まだ一意性の問題がありました。したがって、私が見つけた解決策は、stockID を主キーにせず、代わりに行カウンターを主キーとして使用することでした。

ちなみに、私のコードは非常に遅いので、おそらくこの種の問題に対する最良のアプローチではありませんが、動作します。この量のデータを SQL に取り込むためのより高速な方法を学ぶことは興味深いでしょう。

于 2012-12-27T18:54:39.707 に答える
0

こんにちは、コードを変更する必要があります。

pst.executeUpdate()クエリを持つ最初の for ループで実行しています"INSERT INTO newTestTable2(stockID) VALUES(?)"。内側のループでも、主キーを含まない準備済みステートメントを実行しています。ストック ID は自動インクリメント フィールドではないため、レコードを挿入するときに明示的に渡す必要があります。 .ちなみに、このタスクを実行するために 2 つのループは必要ありません。

于 2012-12-27T03:13:23.080 に答える