2016-05-19 11 views
0

JDBCを使用して3つのテーブルに挿入しようとしています。私のコードのクエリは、MySQL WorkbenchでもRANSが、私はPreparedStatementを使用して、それを実行すると、私はあなたのSQL構文でエラーが発生しているJDBCを使用してテーブルを挿入する

を言ってエラーに遭遇します。

を使用する権利構文についてはMySQLサーバのバージョンに対応するマニュアルを確認してください私のクエリは

BEGIN; 
INSERT INTO user_authentication (enabled, password, username) values (1,'password','username'); 
SET @userId = LAST_INSERT_ID(); 
INSERT INTO account(is_active, balance, user_id) values(1,0.0,@userId); 
INSERT INTO user_information (email, firstname, lastname, user_id) values ('[email protected]','Oleg','Oleg',@userId); 
INSERT INTO user_authorization (role, user_id) values ('ROLE_USER', @userId); 
COMMIT; 

のように見えるそのエラーがそのBEGIN;の文が原因であると思われます。 JDBCとPreparedStatementを使用して複数の挿入クエリを実行するにはどうすればよいですか?

全体の方法は、あなたが少しここで用語を混同している

@Override 
public void save(User user) { 
    Connection conn = null; 
    Account account = user.getAccount(); 
    UserInformation information = user.getUserInformation(); 
    Set<UserAuthorization> roles = user.getRoles(); 
    String insertUserQuery = "INSERT INTO user_authentication (enabled, password, username) values (?,?,?);"; 
    String insertAccountQuery = "INSERT INTO account(is_active, balance, user_id) values(?,?,@userId);"; 
    String insertInformationQuery = "INSERT INTO user_information (email, firstname, lastname, user_id) values (?,?,?,@userId);"; 
    String insertRolesQuery = "INSERT INTO user_authorization (role, user_id) values (?, @userId);"; 
    String query = "BEGIN;" + insertUserQuery 
      + " SET @userId = LAST_INSERT_ID(); " + insertAccountQuery 
      + insertInformationQuery + insertRolesQuery + "COMMIT;"; 
    try { 
     conn = dataSource.getConnection(); 
     PreparedStatement statement = conn.prepareStatement(query); 
     statement.setBoolean(1, true); 
     statement.setString(2, user.getPassword()); 
     statement.setString(3, user.getUsername()); 
     statement.setBoolean(4, true); 
     statement.setDouble(5, account.getBalance()); 
     statement.setString(6, information.getEmail()); 
     statement.setString(7, information.getFirstName()); 
     statement.setString(8, information.getLastName()); 
     for (UserAuthorization role : roles) { 
      statement.setString(9, role.getRole().toString()); 
     } 
     statement.executeUpdate(); 

    } catch (SQLException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 

} 
+0

あなたが直接、BEGIN、COMMIT& –

+0

@YuriのないINSERT INTOは......、はい行うことができますが、私はそのローカル変数を必要とする「@userId」に外部キーを挿入します。そして、それは不自然に3つのJavaメソッド呼び出しからデータベースをトリガするようです。 –

+0

あなたは、私が理解し、バッチ処理があり、Nishant123 @このリンク https://examples.javacodegeeks.com/core-java/sql/jdbc-batch-insert-example/ – Nishant123

答えて

2

のように見えます。複数のステートメント/クエリで構成されるトランザクションを実行しようとしています。

単純にすべての文字列を連結することはできません。 4種類のインサートがあります。したがって、これらの挿入用に4つの(準備された)文オブジェクトをJavaで作成する必要があります。生成されたID(外部キー用)を取得するには、追加のステートメントが必要です。

BEGINとCOMMITについて:PreparedStatementオブジェクトの 'commit()'メソッドを使用する必要があります。 これを参照してくださいOracle JDBC tutorial

注意してください。 con.setAutoCommit(false);この例では です。 JDBCはデフォルトで自動コミットを有効にしているため、最初にオフにする必要があります。

そして、1回のJavaメソッド 呼び出しからデータベースが3回トリガされるようです。

mysqlのworkbenchからスクリプトを実行しても、依然として複数のステートメント/クエリが実行されます。あなたの(ワークベンチ)サンプルコードはdbを7回トリガします。つまり、7回のラウンドトリップワークベンチ< - >データベースがあります。

はい、ただし、外部キーを挿入するには、そのローカル変数 '@userId'が必要です。

あなたに戻っプログラムすなわちに生成されたキーを読んで「LAST_INSERT_ID()を選択」またはより良いこのquestionまたはより良いquestionそれを見て良いです。それを他の行を挿入するためのパラメータとして使用します。

for (UserAuthorization role : roles) { 
    statement.setString(9, role.getRole().toString()); 
} 
statement.executeUpdate(); 

期待した結果が得られません。パラメータを何度も何度も設定しています(データベース内ではなく、プログラム内でのみ)。 PreparedStatmentの利点が説明されているチュートリアルの最上部を参照してください。

これは少し物事をクリア希望が....

+0

ありがとう、私の考えをクリアします。私は 'PreparedStatement文= conn.prepareStatement(insertUserQuery、Statement.RETURN_GENERATED_KEYS)'を使って外部キーを取得しました。また、セミコロン構文はJDBC文には適用できないことがわかりました。そのため、これが 'BEGIN; 'のエラーの原因でした。 –

関連する問題