- PR -

c#+MySqlで文字列の最後に「十」を登録するとエラーになる

1
投稿者投稿内容
ぶじお
常連さん
会議室デビュー日: 2006/05/24
投稿数: 28
投稿日時: 2006-09-13 14:38
お世話になります。過去レスにもありましたが、解決方法がちょっと違うので改めて質問させて下さい。

c#で文字列の最後に「十」など(シフトJISコード:xx5c)を登録しようとすると、ExecuteNonQueryでエラーが発生します。
パラメータを使用しないのであれば出来るのですが、影響範囲が大きいので、出来ればパラメータを使用したいのです、良い解決方法がありましたら、教えて下さい。よろしくお願いします。
以下のソースの「"SQLユーザー十"」を「"SQLユーザー十¥¥"」(¥は半角)も同じです。

●ソース
try
{
OdbcCommand cmd = new OdbcCommand();
string sql;
string connectString = "DSN=ac_myisam;PORT=3306;SERVER=localhost;DATABASE=ac_myisam;UID=root;PWD=PC0134;OPTION=0;DESCRIPTION=ac_myisam";
conn = new OdbcConnection(connectString);
conn.Open();

sql = "set names sjis";
cmd = new OdbcCommand ( sql, conn );
cmd.CommandText = sql;
cmd.ExecuteNonQuery();

sql = "INSERT INTO m_user (user_id, username, password, kengen, kigyou_id) VALUES (?, ?, ?, ?, ?);";
cmd = new OdbcCommand ( sql, conn );
cmd.Parameters.Add ( new OdbcParameter ("user_id", "sqltest"));
cmd.Parameters.Add ( new OdbcParameter ("username", "ユーザー十"));
cmd.Parameters.Add ( new OdbcParameter ("password", "sqltest"));
cmd.Parameters.Add ( new OdbcParameter ("kengen", 1));
cmd.Parameters.Add ( new OdbcParameter ("kigyou_id", 1));

cmd.CommandText = sql;
cmd.ExecuteNonQuery();
}
catch(Exception ex)
{
string msg = ex.Message;
}
finally
{
conn.Close();
}

●エラー
ERROR [23000] You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'sqltest', 1, 1)' at line 1

●環境
WindowsXP Pro(sp2)
Microsoft Development Environment 2003
Microsoft .NET Framework 1.1
mysql 5.0.19
MYSQL ODBC 3.51

●文字コード
Server characterset:sjis
Db characterset:sjis
Client characterset:sjis
Conn. characterset:sjis
かずくん
ぬし
会議室デビュー日: 2003/01/08
投稿数: 759
お住まい・勤務地: 太陽系第三惑星
投稿日時: 2006-09-13 14:55
+をエスケープするか、文字列の最後に半角スペースを付与(+で終わらせなくする)すれば、いけるかもしれない。

...っていうコメントが、おそらく過去ログにもあっただろうなぁ
ぶじお
常連さん
会議室デビュー日: 2006/05/24
投稿数: 28
投稿日時: 2006-09-13 15:12
引用:

かずくんさんの書き込み (2006-09-13 14:55) より:
+をエスケープするか、文字列の最後に半角スペースを付与(+で終わらせなくする)すれば、いけるかもしれない。

...っていうコメントが、おそらく過去ログにもあっただろうなぁ



かずくんさん、回答ありがとうございます。
代替手段として、最後の文字が「xx5c」の場合は、半角スペースを入れています。そうなると、文字数チェックなどに影響があるので、他に方法がないかなと思っている次第で・・・。ただ、最大文字に「xx5c」が入ってくる確率ってかなり低いので良いかなとも思っています。ちょっと気持ち悪いのですが。

かずくん
ぬし
会議室デビュー日: 2003/01/08
投稿数: 759
お住まい・勤務地: 太陽系第三惑星
投稿日時: 2006-09-13 16:56
引用:

ぶじおさんの書き込み (2006-09-13 15:12) より:
代替手段として、最後の文字が「xx5c」の場合は、半角スペースを入れています。そうなると、文字数チェックなどに影響があるので、他に方法がないかなと思っている次第



前後(もしくは後ろの空白を)トリミングした後、文字数チェックすればよいのでは。

もはや、そんな修正に費やす時間はない?
後ろに空白を入力されるため、トリミングできない?
ぶじお
常連さん
会議室デビュー日: 2006/05/24
投稿数: 28
投稿日時: 2006-09-13 17:46
引用:

かずくんさんの書き込み (2006-09-13 16:56) より:
引用:

ぶじおさんの書き込み (2006-09-13 15:12) より:
代替手段として、最後の文字が「xx5c」の場合は、半角スペースを入れています。そうなると、文字数チェックなどに影響があるので、他に方法がないかなと思っている次第



前後(もしくは後ろの空白を)トリミングした後、文字数チェックすればよいのでは。

もはや、そんな修正に費やす時間はない?
後ろに空白を入力されるため、トリミングできない?



もはや、そんな修正に費やす時間はない?-->NGかな
後ろに空白を入力されるため、トリミングできない?-->OK

既に運用中なので、あまり広範囲な修正は避けたいのが本音で。

で、こんな解決策を考えました。
下記の行のように「?」を「RTRIM(?)」にすれば、登録出来るようになりました。

sql = "INSERT INTO m_user (user_id, username, password, kengen, kigyou_id) VALUES (RTRIM(?), RTRIM(?), RTRIM(?), RTRIM(?), RTRIM(?));";

これで、文字数チェックの修正も無く、修正範囲も少なくすみます。
かずくんさん、お手数をおかけ致しました。
ぶじお
常連さん
会議室デビュー日: 2006/05/24
投稿数: 28
投稿日時: 2006-09-14 14:29
引用:

ぶじおさんの書き込み (2006-09-13 17:46) より:
引用:

かずくんさんの書き込み (2006-09-13 16:56) より:
引用:

ぶじおさんの書き込み (2006-09-13 15:12) より:
代替手段として、最後の文字が「xx5c」の場合は、半角スペースを入れています。そうなると、文字数チェックなどに影響があるので、他に方法がないかなと思っている次第



前後(もしくは後ろの空白を)トリミングした後、文字数チェックすればよいのでは。

もはや、そんな修正に費やす時間はない?
後ろに空白を入力されるため、トリミングできない?



もはや、そんな修正に費やす時間はない?-->NGかな
後ろに空白を入力されるため、トリミングできない?-->OK

既に運用中なので、あまり広範囲な修正は避けたいのが本音で。

で、こんな解決策を考えました。
下記の行のように「?」を「RTRIM(?)」にすれば、登録出来るようになりました。

sql = "INSERT INTO m_user (user_id, username, password, kengen, kigyou_id) VALUES (RTRIM(?), RTRIM(?), RTRIM(?), RTRIM(?), RTRIM(?));";

これで、文字数チェックの修正も無く、修正範囲も少なくすみます。
かずくんさん、お手数をおかけ致しました。




もう1つ問題が発生しました。
DataTableを使ったテーブルの追加、更新も同じ現象が発生してますが、対処方法が解らないのと、修正量が少ないので、とりあえず、sql文を作成で回避しました。
お騒がせ致しました。

Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2006-09-14 22:42
なんか、危険な香り。。。
引用:

コード:
try
{
    OdbcCommand cmd = NULL;//new OdbcCommand();(1)
    string sql; 
    string connectString = "DSN=ac_myisam;PORT=3306;SERVER=localhost;DATABASE=ac_myisam;UID=root;PWD=PC0134;OPTION=0;DESCRIPTION=ac_myisam";(2)
    conn = new OdbcConnection(connectString);
    conn.Open();

    sql = "set names sjis";
    cmd = new OdbcCommand ( sql, conn );
    //cmd.CommandText = sql;(3)
    cmd.ExecuteNonQuery();
    cmd.Dispose();(4)

    sql = "INSERT INTO m_user (user_id, username, password, kengen, kigyou_id) VALUES (?, ?, ?, ?, ?);";
    cmd = new OdbcCommand ( sql, conn );
    cmd.Parameters.Add ( new OdbcParameter ("user_id", "sqltest"));
    cmd.Parameters.Add ( new OdbcParameter ("username", "ユーザー十"));
    cmd.Parameters.Add ( new OdbcParameter ("password", "sqltest"));
    cmd.Parameters.Add ( new OdbcParameter ("kengen", 1));
    cmd.Parameters.Add ( new OdbcParameter ("kigyou_id", 1));

    //cmd.CommandText = sql; (5)
    cmd.ExecuteNonQuery();
    cmd.Dispose();(6)
//}
//catch(Exception ex)
//{
    //string msg = ex.Message;(7)
}
finally
{
    conn.Close();
}




1) 使わないものを new する必要はない。
2) UID が root って ( ・_・
 パスワードも、マシン名のような気がするなぁ。。。
3) コンストラクタで放り込んでいるので必要ない。
4) Dispose メソッドを持っているものは、とりあえず呼べ。
5) 3 に同じ。
6) 4 に同じ。
7) 意味のないキャッチはしない。
ぶじお
常連さん
会議室デビュー日: 2006/05/24
投稿数: 28
投稿日時: 2006-09-21 10:03
[quote]
Jittaさんの書き込み (2006-09-14 22:42) より:
なんか、危険な香り。。。
引用:

1) 使わないものを new する必要はない。
2) UID が root って ( ・_・
 パスワードも、マシン名のような気がするなぁ。。。
3) コンストラクタで放り込んでいるので必要ない。
4) Dispose メソッドを持っているものは、とりあえず呼べ。
5) 3 に同じ。
6) 4 に同じ。
7) 意味のないキャッチはしない。



Jittaさん、遅くなってすみません。
いつも大変勉強になってます。
useridやpasswordなどは、コードを変えた方がよかったですね。
私もrootってとは思っていましたが、テスト端末をお借りしているので・・・。
では。
1

スキルアップ/キャリアアップ(JOB@IT)