竹形様
いつもお世話になっています。
MySQLのmy.iniの設定は
エラーを回避する良い方法はありますでしょうか。ご教示おねがいします。
いつもお世話になっています。
MySQLのmy.iniの設定は
default-character-set=cp932
で、JSPでは<%@ page language="java" contentType="text/html;
charset=Windows-31J"%>
<% request.setCharacterEncoding("Windows-31J");%>
と設定してありますが、MySQLへ@ABや−(全角の横棒)をセットしようとするとエラーで落ちてしまいます。以下がエラーコードです。charset=Windows-31J"%>
<% request.setCharacterEncoding("Windows-31J");%>
エラーを回避する良い方法はありますでしょうか。ご教示おねがいします。
javax.servlet.ServletException: java.sql.SQLException: Incorrect string value: '\xEF\xBC\x8D\xEF\xBC\x8D...' for column 'theme' at row 1
org.apache.jasper.runtime.PageContextImpl.doHandlePageException(PageContextImpl.java:852)
org.apache.jasper.runtime.PageContextImpl.handlePageException(PageContextImpl.java:781)
org.apache.jsp.hatugentouroku_jsp._jspService(hatugentouroku_jsp.java:141)
org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:374)
org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:342)
org.apache.jasper.servlet.JspServlet.service(JspServlet.java:267)
javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
原因
java.sql.SQLException: Incorrect string value: '\xEF\xBC\x8D\xEF\xBC\x8D...' for column 'theme' at row 1
com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1055)
com.mysql.jdbc.SQLError.createSQLException(SQLError.java:956)
com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3515)
com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3447)
com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1951)
com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2101)
com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2554)
com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:1761)
com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2046)
com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:1964)
com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:1949)
org.apache.jsp.hatugentouroku_jsp._jspService(hatugentouroku_jsp.java:111)
org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:374)
org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:342)
org.apache.jasper.servlet.JspServlet.service(JspServlet.java:267)
javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
org.apache.jasper.runtime.PageContextImpl.doHandlePageException(PageContextImpl.java:852)
org.apache.jasper.runtime.PageContextImpl.handlePageException(PageContextImpl.java:781)
org.apache.jsp.hatugentouroku_jsp._jspService(hatugentouroku_jsp.java:141)
org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:374)
org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:342)
org.apache.jasper.servlet.JspServlet.service(JspServlet.java:267)
javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
原因
java.sql.SQLException: Incorrect string value: '\xEF\xBC\x8D\xEF\xBC\x8D...' for column 'theme' at row 1
com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1055)
com.mysql.jdbc.SQLError.createSQLException(SQLError.java:956)
com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3515)
com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3447)
com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1951)
com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2101)
com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2554)
com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:1761)
com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2046)
com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:1964)
com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:1949)
org.apache.jsp.hatugentouroku_jsp._jspService(hatugentouroku_jsp.java:111)
org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:374)
org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:342)
org.apache.jasper.servlet.JspServlet.service(JspServlet.java:267)
javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
投稿:スワジランド[swajiland]/2009年 03月 04日 20時 16分
/更新:2009年 03月 04日 20時 16分
RE:@A−などの文字をMySQLへ登録する方法を教えてください。
by 竹形 誠司[takegata]
MySQLがcp932でJSPがWindows-31Jなら大丈夫だと思うんですけどねぇ。
私はコードを書く環境をutf-8に揃えているので、すぐには試せないのですが、環境を作って再現するかどうかやってみます。お使いのMySQLのバージョンとJDBCドライバのバージョンを教えていただけますか?
私はコードを書く環境をutf-8に揃えているので、すぐには試せないのですが、環境を作って再現するかどうかやってみます。お使いのMySQLのバージョンとJDBCドライバのバージョンを教えていただけますか?
投稿:竹形 誠司[takegata]/2009年 03月 04日 20時 29分
/更新:2009年 03月 06日 00時 06分
竹形様
いつも無理を言いまして申し訳ありません。
MySQLのバージョンはv5.1.0で
MySQL-connctor-jarは5.1.7であります。
よろしくお願いいたします。
いつも無理を言いまして申し訳ありません。
MySQLのバージョンはv5.1.0で
MySQL-connctor-jarは5.1.7であります。
よろしくお願いいたします。
投稿:スワジランド[swajiland]/2009年 03月 04日 20時 52分
/更新:2009年 03月 04日 20時 52分
↑の環境でテストしてみましたが、エラーにはなりませんでした。
おそらく、MySQLのデータベースがsjis用に作られているのではないかと思います。show create database コマンドで調べてみてください。testというデータベースのデフォルトキャラクタセットを調べるには、mysqlのプロンプトで次のようなSQL文を入力します。
作成済みのデータベースのデフォルトキャラクタセットを変更するには、SQLのALTER文を使って次のように書きます。
テーブルも同様に、作成済みのものはALTER文でデフォルトキャラクタセットを変更する必要があります。
おそらく、MySQLのデータベースがsjis用に作られているのではないかと思います。show create database コマンドで調べてみてください。testというデータベースのデフォルトキャラクタセットを調べるには、mysqlのプロンプトで次のようなSQL文を入力します。
mysql> show create database test;
my.iniのdefault-character-setの設定は、create database を実行したときにデータベースに記録されます。そのため、my.iniを編集してdefault-character-setの設定を変えても、それ以降に作られたデータベースでしかその設定は有効になりません。これはなかなか気がつきにくい所なので、結構ハマる人がいるようです。私もハマりました。作成済みのデータベースのデフォルトキャラクタセットを変更するには、SQLのALTER文を使って次のように書きます。
alter database test default character set = utf8;
utf-8を指定する場合はハイフンを入れずにutf8と書きます。これはmysqlの仕様で、Windows-31Jの場合はcp932(mysqlのバージョンによってはms932)、Shift_JISの場合はsjis、EUCの場合はujisです。テーブルも同様に、作成済みのものはALTER文でデフォルトキャラクタセットを変更する必要があります。
投稿:竹形 誠司[takegata]/2009年 03月 05日 05時 25分
/更新:2009年 03月 05日 05時 28分
竹形様
ご指摘のとおり、データベース、テーブルともデフォルトチャラクターセットがsjisになっていました。alterコマンドでデータベース、テーブルともcp932に変更しましたが、show create table でテーブルの構成を見るとのvarchar設定のカラムがsjisのままになっています。
このカラムのデフォルトチャラクターセットをcp932に変更できますでしょうか?コマンドをご教示おねがいいたします。
ご指摘のとおり、データベース、テーブルともデフォルトチャラクターセットがsjisになっていました。alterコマンドでデータベース、テーブルともcp932に変更しましたが、show create table でテーブルの構成を見るとのvarchar設定のカラムがsjisのままになっています。
このカラムのデフォルトチャラクターセットをcp932に変更できますでしょうか?コマンドをご教示おねがいいたします。
投稿:スワジランド[swajiland]/2009年 03月 05日 23時 12分
/更新:2009年 03月 05日 23時 12分
テーブル名がtestだとして、
テーブルに必要なデータが入っていない場合はテーブルを削除して作り直してしまった方が早いかも知れません。既にデータが入っている場合はmysqldump等でバックアップを取ってから操作してくださいね。
alter table test convert to character set cp932;
で、どうでしょう。テーブルに必要なデータが入っていない場合はテーブルを削除して作り直してしまった方が早いかも知れません。既にデータが入っている場合はmysqldump等でバックアップを取ってから操作してくださいね。
投稿:竹形 誠司[takegata]/2009年 03月 05日 23時 28分
/更新:2009年 03月 05日 23時 29分
竹形様
スッキリ解決しました!!やったー
ビューティフルです。すばらしすぎます。
神様、仏様、救世主の竹形様。
何とお礼を申し上げてよいのか、
いつも助けていただきまして、
感謝、感謝、感謝でございます。
本当にありがとうございました。
また、道に迷いましたらよろしくおねがいいたします。
スッキリ解決しました!!やったー
ビューティフルです。すばらしすぎます。
神様、仏様、救世主の竹形様。
何とお礼を申し上げてよいのか、
いつも助けていただきまして、
感謝、感謝、感謝でございます。
本当にありがとうございました。
また、道に迷いましたらよろしくおねがいいたします。
投稿:スワジランド[swajiland]/2009年 03月 05日 23時 54分
/更新:2009年 03月 05日 23時 54分
いや・・・まぁ、それほどでも・・・どういたしまして・・・・
っていうか、恥ずかしいじゃないですか!(笑)
次に本を書くときにネタにさせてもらいますよ。
っていうか、恥ずかしいじゃないですか!(笑)
次に本を書くときにネタにさせてもらいますよ。
投稿:竹形 誠司[takegata]/2009年 03月 06日 00時 03分
/更新:2009年 03月 06日 00時 03分
私も最近業務システムでsjisのMySQLを扱っていて困っていましたが
Javaからjdbcに文字列を渡す際に以下の関数を噛ますことで解決しました。
import javax.xml.bind.DatatypeConverter;
private String toHexString(String value)
{
try
{
byte[] data = value.getBytes("Windows-31J");
String hex = DatatypeConverter.printHexBinary(data);
if (hex.length() > 0) {
return "0x" + hex;
}
return "''";
}
catch (UnsupportedEncodingException e)
{
e.printStackTrace();
}
return "'" + value + "'";
}
MySQLは文字列を16進数のデータで登録できますので
データを一旦16進数文字列へ変換かけることで
jdbcの出来の悪いパーサをスルーさせることが出来ます。
Javaからjdbcに文字列を渡す際に以下の関数を噛ますことで解決しました。
import javax.xml.bind.DatatypeConverter;
private String toHexString(String value)
{
try
{
byte[] data = value.getBytes("Windows-31J");
String hex = DatatypeConverter.printHexBinary(data);
if (hex.length() > 0) {
return "0x" + hex;
}
return "''";
}
catch (UnsupportedEncodingException e)
{
e.printStackTrace();
}
return "'" + value + "'";
}
MySQLは文字列を16進数のデータで登録できますので
データを一旦16進数文字列へ変換かけることで
jdbcの出来の悪いパーサをスルーさせることが出来ます。
投稿:takahashi[pneuma]/2015年 05月 26日 10時 02分
/更新:2015年 05月 26日 10時 05分