
© 1995-2008 MySQL AB, 2008-2009 Sun Microsystems, Inc.
所用で C# から MySQL :: Connector/Net 6.0 を利用して MySQL からデータを抜く必要があったため、コーディングしていたのですが
Fatal error encountered during command execution
といったエラーが。
原因は直ぐに特定できたのですが、どうにも腑に落ちない。
というのも、原因は条件式の検索文字列の先頭に「@」が付いているため、変数として誤認されるのが原因で回避策は後回しとして、通常の SELECT 文とプロシージャコールで挙動が異なること。
プロシージャは以下のような感じ。これで同様のエラーが発生することはなく、問題なく動作してしまう。
string hoge = "@abc";
string fuga = "asdf1234";
string query = string.Format("call proc_Test('{0}', '{1}');", hoge, fuga);
一方、通常の SELECT 文だと先述したプロシージャのようなコーディングを行うと Fatal error encountered during command execution と怒られてしまう。
対処方法としては以下のような感じにする必要がある。
string cns = "MySQL接続文字列";
string hoge = "@abc";
string fuga = "asdf1234";
string query = string.Format(
"select * from atTest where testName=@TEST and testPass='{0}';", fuga);
using (MySqlConnection conn = new MySqlConnection(cns))
{
MySqlCommand cmd = new MySqlCommand(query, conn);
cmd.Parameters.Add(new MySqlParameter(
"@TEST", MySqlDbType.VarChar, 40));
cmd.Parameters["@TEST"].Value = hoge;
cmd.CommandTimeout = 300;
conn.Open();
// 処理
conn.Close();
}
後者も完璧ではないけども(fuga 変数の内容も本来であれば、Parameters に Add するべきなんだけど)プロシージャの場合は問題無いのはどういうことだろう?
Conncector/Net のバグなのか仕様なのか……。
official.MySQL Query Analyzer – Improving SQL Query Performance
Filed under: C#, MySQL | Comment (0)
サクッと終わらせるつもりが、結構時間を食われたので忘れないようにメモ?。
事の発端は MySQL レプリケーションのスレーブ側が、上手くデータを更新できなかった場合に直ぐメールを携帯に飛ばして対応できるようにしたかった。毎日スレーブ側で show slave status\G を叩くのも面倒なんで。
で、show slave status を叩いた結果で欲しい情報が以下。
- Slave_IO_State
- Slave_IO_Running
- Slave_SQL_Running
- Last_Errno
- Last_Error
まぁ、普通に外部から MySQL へアクセスして必要なデータを抜いて、指定メールアドレスへメールを送信するだけの簡単なお仕事のプログラムを作って、ローカルでもデバッグ&テスト完了。いざサーバーへ実装&動作テストをしてみたら変な現象が。
◆カテゴリ
◇ホスト1
Slave_IO_State: System.Byte[]
Slave_IO_Running: System.Byte[]
Slave_SQL_Running: System.Byte[]
Last_Errno: 0
Last_Error: System.Byte[]
◇ホスト2
Slave_IO_State: System.Byte[]
Slave_IO_Running: System.Byte[]
Slave_SQL_Running: System.Byte[]
Last_Errno: 1064
Last_Error: System.Byte[]
System.Byte[] ってあんた……。
バイト配列が帰ってくるなら仕方ない。バイト配列をキャラクター配列に変換してーって、ローカルじゃ正常動作するからデバッグが出来ない?!いや、出来るけど肝心の部分がブラックボックスっぽくなっているのでイマイチ。
肝心の部分はというと、こんなカンジ。
(一部抜粋でもソース貼り付けって恥ずかしいのね)
string slaveIOStatus = reader["Slave_IO_State"].ToString();
string slaveIORunning = reader["Slave_IO_Running"].ToString();
string slaveSQLRunning = reader["Slave_SQL_Running"].ToString();
string lastErrNo = reader["Last_Errno"].ToString();
string lastError = reader["Last_Error"].ToString();
対象のサーバー
に対して、MySQL ODBC Driver 3.51 を使用して接続。
四苦八苦しても直らない。他プログラムではどうってことないのだけども。
あえて違うというと、DB User の権限?SUPER, REPLICATION CLIENT しか権限を与えていない。あとは、接続時の Database を指定していない。
で、結局のところ以下のようにソースを修正したら直った。
string slaveIOStatus = reader.GetString(0);
string slaveIORunning = reader.GetString(10);
string slaveSQLRunning = reader.GetString(11);
string lastErrNo = reader.GetString(18);
string lastError = reader.GetString(19);
期待値のメール内容はこんなカンジ。
◆カテゴリ
◇ホスト1
Slave_IO_State:
Slave_IO_Running: No
Slave_SQL_Running: Yes
Last_Errno: 0
Last_Error:
◇ホスト2
Slave_IO_State:
Slave_IO_Running: No
Slave_SQL_Running: No
Last_Errno: 1064
Last_Error: Error ‘You have an error in your SQL syntax; ‘ (略
DNS じゃないけど、名前解決的なことができていなかったっぽい。
取り急ぎソース修正で対応できたけども……。危険な気がする。
Filed under: C#, MySQL | Comment (0)