web-dev-qa-db-ja.com

mysqlは重複キーで行全体を更新します

これはjspコードです

 PreparedStatement pstmt =con.prepareStatement("select ssn,name,gender,bod,address,profession,phone from contacts ");
        ResultSet rss = pstmt.executeQuery();

        while(rss.next()){
            stmt = conn.createStatement();
String sql1 = "INSERT INTO contacts (id,ssn,name,gender,dob,address,profession,phone) VALUES (default,'" +rss.getString(1) + "','"+rss.getString(2) + "','"+rss.getString(3)+"','" +rss.getString(4) + "','"+rss.getString(5) +"','"+rss.getString(6)+"','"+rss.getString(7)+"' on duplicate key update ssn=VALUES("+rss.getString(1)+")";
            stmt.executeUpdate(sql1);
            out.println("<tr style='background-color:white'>");
            out.println("<td>");        out.println(rss.getString(1));out.println("</td>");
            out.println("<td>");        out.println(rss.getString(2));out.println("</td>");
            out.println("<td>");        out.println(rss.getString(3));out.println("</td>");
            out.println("<td>");        out.println(rss.getString(4));out.println("</td>");
            out.println("<td>");        out.println(rss.getString(5));out.println("</td>");
            out.println("<td>");        out.println(rss.getString(6));out.println("</td>");
            out.println("<td>");        out.println(rss.getString(7));out.println("</td>");         
out.println("</tr>");
                            }

出力:

com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException:SQL構文にエラーがあります。MySQLサーバーのバージョンに対応するマニュアルで、重複したキーの更新ssn = VALUESの近くで使用する正しい構文を確認してください(1) '1行目

注:サーバーバージョン:5.7.10-log MySQL Community Server

1
adamoxy

使いました:

_INSERT INTO contacts 
    (id, ssn, name, gender, dob, address, profession, phone) 
VALUES 
    (default, 1, 2, 3, 4, 5, 6, 7) 
ON DUPLICATE KEY UPDATE
    ssn = VALUES(1) ;
_

ここで_1, 2, 3, .._はアプリケーションから渡される値です(ちなみにメソッドを確認してください。SQLインジェクションに対して脆弱のようです)

表示されるエラーは、VALUES(1)が有効な構文ではないためです。最後の行は次のいずれかである必要があります。

_    ssn = 1 ;               -- the value , repeated
_

または:

_    ssn = VALUES(ssn) ;     -- reference to the value that was 
                            -- to be inserted to column "ssn"  
_
2
ypercubeᵀᴹ

ループ内にクエリがある場合は常に、SQLでsingleクエリを使用してループを実行できるかどうかを検討します。つまり、実際にはループではありません。

INSERT INTO contacts 
             (ssn, name, gender, dob, address, profession, phone) 
    ON DUPLICATE KEY UPDATE
        ssn = VALUES(ssn),
        name = VALUES(name),
        ...
    SELECT ssn, name, gender, dob, address, profession, phone
        FROM ...

または、単に

INSERT IGNORE INTO contacts (ssn, ...)
    SELECT ssn, ... FROM ...

しかし...これは意味がありません。 contactsのすべての行を読み取り、それらをsameテーブルに挿入していますか?どういう意味ですか?

ssnUNIQUEキーであると想定しています。そうしないと、IODKUが機能しない場合があります。

idは、どのバリアントでも指定する必要がないことに注意してください。 AUTO_INCREMENTおよびPRIMARY KEY。しかし、なぜidがあるのですか? PKとしてSSNを使用するだけです。

深刻なセキュリティコンサルティングが必要-マシンがハッキングされた場合、SSNにより深刻な法的責任が問われる可能性があります。

0
Rick James