所用で 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);
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();
}
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
