
とあるプロジェクト(C#)で、今まで Oracle だけに接続していたのが、SQL Server への接続も追加になりました。
Oracle への接続は「Oracle.ManagedDataAccess.Client」を使っていましたが、
SQL Server への接続は、「System.Data.SqlClient」を使う事になりました。
※本当ならデータベースに依存しないように「System.Data.Common」を使って、
プロバイダファクトリ的に作るべきなのでしょうが、途中から変更するのが大人の事情で難しかったです・・・。
と言う事で、Oracleへの接続クラスをコピーして、使用するクラスなどを変えていざ実行してみると、
- "Message": "An error has occurred.",
- "ExceptionMessage": "SqlCommand.Prepare requires all variable length parameters to have an explicitly set non-zero Size",
- "ExceptionType": "System.ApplicationException",
「可変長パラメータには、必ずゼロ以外のサイズを指定しろ」と言っていますね。
確かに、プログラム的には、
となっていて、サイズを指定していません。
- string sql =
- "SELECT login_id"
- + ",user_name "
- + "FROM authentication_info "
- + "WHERE user_identifier = :user_identifier "
- + "AND hoge_code = :hoge_code ";
- 〜中略〜
- SqlParameter parameter1 = this._cmd.CreateParameter();
- parameter1.Value = "123";
- parameter1.ParameterName = ":user_identifier";
- parameter1.DbType = DbType.String;
- SqlParameter parameter2 = this._cmd.CreateParameter();
- parameter2.Value = "123";
- parameter2.ParameterName = ":hoge_code";
- parameter2.DbType = DbType.String;
- this._cmd.Parameters.Add(parameter1);
- this._cmd.Parameters.Add(parameter2);
「Oracle.ManagedDataAccess.Client」では不要でも、
「System.Data.SqlClient」では必要なんですね。
と言うわけで、プログラムも以下の様に変更します。
これで問題なく実行出来ました。
- string sql =
- "SELECT login_id"
- + ",user_name "
- + "FROM authentication_info "
- + "WHERE user_identifier = @user_identifier "
- + "AND hoge_code = @hoge_code ";
- 〜中略〜
- SqlParameter parameter1 = this._cmd.CreateParameter();
- parameter1.Value = "123";
- parameter1.ParameterName = ":user_identifier";
- parameter1.DbType = DbType.String;
- parameter1.Size = parameter1.Value.ToString().Length; // 追加
- SqlParameter parameter2 = this._cmd.CreateParameter();
- parameter2.Value = "123";
- parameter2.ParameterName = ":hoge_code";
- parameter2.DbType = DbType.String;
- parameter2.Size = parameter2.Value.ToString().Length; // 追加
- this._cmd.Parameters.Add(parameter1);
- this._cmd.Parameters.Add(parameter2);
ちなみに、「Oracle.ManagedDataAccess.Client」でのプリペアドステートメントには「:(コロン)」を使いますが、「System.Data.SqlClient」では「@(アットマーク)」を使います。
今回の話は大した話ではないのですが、
「Oracle.ManagedDataAccess.Client」では問題無かった、と言う部分がハマりどころなので、
わざわざ記事にしてみました。
C# , SQL Server